powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Умножение записей - multiply
8 сообщений из 8, страница 1 из 1
Умножение записей - multiply
    #39927744
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для решения одной специфической задачи мне пришлось группировать записи и умножить значения, а не просуммировать. Дело в том, что существует агрегатная функция суммирования (SUM), а вот умножения (Multiply) – нет. Как быть?
Чтобы решить данную задачу можно придумать функцию, можно также воспользоваться курсором. Но такие методы, как правило, работают медленно, если речь о большом количестве записей.
На просторах интернета я встретил самую необычную и изящную идею. Тот, кто додумался до этого, просто гений! Я бы сам никогда не додумался. Метод настолько очаровал меня, что я решил поделиться им. Оказывается агрегатной функции SUM вполне достаточно! Но вот только придётся изощряться. Дело в том, что сумма логарифмов с одинаковым основанием равняется как раз таки логарифму точно с таким основанием, но с умножением значений. Т.е.:
LN(A1) + LN(A2) + … + LN(An) = LN(A1*A2*…*An)
Чтобы избавиться от логарифма полученное таким образом значение потом нужно будет воздвигать в степень e.
Правда тут есть нюансы: все умножаемые числа должны быть больше 0, а для этого придётся брать только абсолютное значение и параллельно вести учёт знаков. Ну и в случае нулевого значения добавить «костыль».
Пример:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
WITH N AS (SELECT 1 AS ID, 2 AS VAL FROM DUAL
    UNION ALL SELECT 1, 115 FROM DUAL
    UNION ALL SELECT 1, -17 FROM DUAL
    UNION ALL SELECT 2,  19 FROM DUAL
    UNION ALL SELECT 2,  13 FROM DUAL
    UNION ALL SELECT 3,  24 FROM DUAL
    UNION ALL SELECT 3,  10 FROM DUAL
    UNION ALL SELECT 3,  15 FROM DUAL
    UNION ALL SELECT 3,   7 FROM DUAL
    UNION ALL SELECT 4,   1 FROM DUAL
    UNION ALL SELECT 4,   0 FROM DUAL)
SELECT ID, EXP(SUM(LN(CASE WHEN N.VAL=0 THEN 1 ELSE ABS(N.VAL) END)))
       * POWER(-1, (SUM(CASE WHEN N.VAL<0 THEN 1 ELSE 0 END)))
       * MIN(CASE WHEN N.VAL=0 THEN 0 ELSE 1 END) AS MULTIPLICATION
FROM N
GROUP BY ID
ORDER BY 1;


Выражение « POWER(-1, (SUM(CASE WHEN N.VAL<0 THEN 1 ELSE 0 END))) » необходимо чтобы следить за знаком (в случае если окажется отрицательное число).
Выражение « MIN(CASE WHEN N.VAL=0 THEN 0 ELSE 1 END) » необходимо для выяснения нет ли 0 среди умножаемых значений.
Если Вы точно знаете, что все умножаемые значения больше нуля, то и текст запроса будет проще.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
WITH N AS (SELECT 1 AS ID, 2 AS VAL FROM DUAL
    UNION ALL SELECT 1, 115 FROM DUAL
    UNION ALL SELECT 1,  17 FROM DUAL
    UNION ALL SELECT 2,  19 FROM DUAL
    UNION ALL SELECT 2,  13 FROM DUAL
    UNION ALL SELECT 3,  24 FROM DUAL
    UNION ALL SELECT 3,  10 FROM DUAL
    UNION ALL SELECT 3,  15 FROM DUAL
    UNION ALL SELECT 3,   7 FROM DUAL
    UNION ALL SELECT 4, 0.7 FROM DUAL
    UNION ALL SELECT 4,   1 FROM DUAL
    UNION ALL SELECT 4, 0.5 FROM DUAL)
SELECT ID, EXP(SUM(LN(N.VAL))) AS MULTIPLICATION
FROM N
GROUP BY ID
ORDER BY 1;



P.S.
Конечно же при этом нужно учесть, что если умножаемых чисел слишком много или же сами числа достаточно огромные, то может возникнуть ошибка переполнения.
...
Рейтинг: 0 / 0
Умножение записей - multiply
    #39927749
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studieren
На просторах интернета я встретил самую ...
Для излияния открытий из интернета в интернет больше подходит форма личного блога, не форума. Впрочем, для данного форума воодушевление от очередного секрета Полишинеля не ново 39188 .
...
Рейтинг: 0 / 0
Умножение записей - multiply
    #39927751
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studieren
Метод настолько очаровал меня, что я решил поделиться им.
Тут колумб и америго веспуччи отдыхают - именно ты, и неожиданно для всех, открыл америку.
...
Рейтинг: 0 / 0
Умножение записей - multiply
    #39927756
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-,

Sorry. Я лично не видел этот топик раньше, хотя предварительно конечно же пользовался поиском. Стало быть плохо искал.
...
Рейтинг: 0 / 0
Умножение записей - multiply
    #39927850
Фотография orawish
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studieren,

однозначно, плохо искал

stff групповая функция умножения
...
Рейтинг: 0 / 0
Умножение записей - multiply
    #39927869
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studieren,

что-то напомнило....

YouTube Video
...
Рейтинг: 0 / 0
Умножение записей - multiply
    #39927885
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studieren,

studierenЧтобы решить данную задачу можно придумать функцию, можно также воспользоваться курсором. Но такие методы, как правило, работают медленно, если речь о большом количестве записей.

Для данного форума это на 100% ложное утверждение.
именно со специализированной пользовательской агрегатной функцией и работать будет удобнее,
и работать она будет гарантированно быстреe, по крайней мере на типе number.
Просто попробуй переписать это для случая применения в качестве аналитической функции - и так куча скобок,
а получится не читаемая кракозябра.
А вообще, имхо, такого рода штуки сами по себе не интересны, без воодушевляющего примера практически полезного использования.
...
Рейтинг: 0 / 0
Умножение записей - multiply
    #39927890
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby,

удобнее, быстрее, ещё и точнее....
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Умножение записей - multiply
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]