Архив Категории: Oracle

SQL and PL/SQL

Разбиение суммы на монетки

Сумму в S рублей нужно разбить монетами по 1, 2 или 5 рублей.

WITH t
     AS (    SELECT LEVEL n
               FROM DUAL
         CONNECT BY LEVEL <= :S)
SELECT t1.n || ' по 1 рублю, ' ||
       t2.n || ' по 2 рубля, ' ||
       t3.n || ' по 5 рублей'
  FROM t t1, t t2, t t3
 WHERE 1 * t1.n + 2 * t2.n + 5 * t3.n = :S
 ORDER BY t1.n DESC, t2.n DESC, t3.n DESC
SQL and PL/SQL

Простые числа

Знаменитая задачка про поиск простых чисел средствами чистого SQL. Используется обобщенное табличное выражение — иерархический запрос, отбирающий все натуральные числа вплоть до максимального, определяемого параметром S, и полный перебор с дополнительным условием, что возможные делители проверяемого на простоту числа нужно искать среди чисел вплоть до квадратного корня из этого числа.

WITH t
     AS (    SELECT LEVEL n, LEVEL * LEVEL n2
               FROM DUAL
         CONNECT BY LEVEL <= :S)
SELECT t1.n
  FROM t t1
 WHERE NOT EXISTS
          (SELECT 1
             FROM t t2
            WHERE t1.n >= t2.n2 
              AND t2.n != 1 
              AND MOD(t1.n, t2.n) = 0)

P.S. Способ полностью рабочий, но не самый быстрый. Скорее, классический в плане знаний диалекта SQL от Oracle и обобщенных выражений.

Analyses and Dashboards

Форматирование больших чисел в отчетах BI Answers

Как известно, при выводе больших чисел (как пример, цифр отчета о прибылях и убытках) OBIEE по непредсказуемому алгоритму отбрасывает значащие знаки после 15-ой цифры, иногда это может проявиться в десятичных знаках, а при слишком больших числах и в единицах, десятках, тысячах. Чтобы преодолеть это ограничение, в выражении для числовых столбцов реализовано преобразование числа в строку при помощи функции TO_CHAR():

SELECT
    TO_CHAR(12345678901234567890.09,
            '999G999G999G999G999G999G999G990D99',
            'nls_language=english')
  FROM DUAL;

Вывод при этом, конечно, текстовый, но со всеми значащими цифрами:

    12,345,678,901,234,567,890.09

В одном из запросов на изменение понадобилось в этом выводе подставлять пробелы вместо запятых в разделителях тысяч. Это решается таким способом:

SELECT
    TO_CHAR(12345678901234567890.09,
            '999G999G999G999G999G999G999G990D99',
            'nls_numeric_characters = ''. ''')
  FROM DUAL;

Результат радует:

    12 345 678 901 234 567 890.09

Остается добавить в отчете Answers выравнивание по правой границе и формат отображения текстовый с неразрывными пробелами, и отчет прекрасно выглядит! Конечно, при выгрузке в Excel форматирование чисел остается текстовым, но Заказчик согласен на такие условия.