Поэтому я немного искал и обнаружил , что вы можете создать произведение строк в Oracle, используя GROUP BY и изящную математическую формулу: exp(sum(ln(some_col)))
.Это довольно круто, но, к сожалению, не работает, когда some_col
потенциально равен нулю (потому что ln(0)
невозможно, поскольку ln (x) - отрицательная бесконечность, когда приближается к нулю).
Пример запроса:
select
a, b, c
sum(d) d,
sum(e) e,
exp(sum(ln(f))) f
from x
group by a, b, c;
Очевидно, поскольку это произведение значений, если одно из них равно нулю, произведение будет равно нулю.Непосредственной мыслью было бы использовать case
, но для этого требовалось бы, чтобы оператор case был на агрегированном значении или что-то в GROUP BY ... что это не так.Я не могу просто исключить эти строки, потому что мне все еще нужны sum(d)
и sum(e)
.
Есть какие-нибудь мысли о хорошем способе сделать это, имея дело с потенциальными нулями?Я думал о чем-то, касающемся over(partition by ...)
, но на самом деле мои запросы группируются по 12 столбцам и объединяются еще 20 столбцов.Этот запрос может показаться ужасным, но если это единственное решение, я полагаю, у меня нет выбора.
Дополнительный вопрос: есть ли какая-то конкретная причина, по которой в Oracle нет функции продукта?Похоже, было бы так просто включить такую вещь, как sum
is.
Примечание: Это Oracle 12c.
Пример:
Если бы у меня была такая таблица ввода (в соответствии с запросом выше):
| a | b | c | d | e | f |
+-----+-----+-----+---+---+---+
| foo | bar | hoo | 1 | 2 | 2 |
| foo | bar | hoo | 3 | 4 | 3 |
| foo | bar | hoo | 2 | 5 | 0 |
| foo | bar | mee | 1 | 2 | 2 |
| foo | bar | mee | 3 | 4 | 3 |
Я бы ожидал, что вывод будет выглядеть так:
| a | b | c | d | e | f |
+-----+-----+-----+---+----+---+
| foo | bar | hoo | 6 | 11 | 0 |
| foo | bar | mee | 4 | 6 | 6 |
Однако, поскольку третья строка имеет0 для f
, мы, естественно, получаем ORA-01428: argument '0' is out of range
для ln(0)
.