Подходът на логаратъм/степен е най-често използваният подход. За Oracle това е:
select exp(sum(ln(col)))
from table;
Не знам защо първоначалните дизайнери на бази данни не са включили PRODUCT()
като агрегираща функция. Най-доброто ми предположение е, че всички те са били компютърни учени, без статистици. Такива функции са много полезни в статистиката, но не се показват много в компютърните науки. Може би не са искали да се справят с проблемите на препълването, които такава функция би предполагала (особено при цели числа).
Между другото, тази функция липсва в повечето бази данни, дори в тези, които прилагат много функции за статистическо агрегиране.
редактиране:
Проблемът с отрицателните числа го прави малко по-сложен:
select ((case when mod(sum(sign(col)), 2) = 0 then 1 else -1 end) *
exp(sum(ln(abs(col))))
) as product
Не съм сигурен за безопасен начин в Oracle за обработка на 0
с. Това е "логичен" подход:
select (case when sum(case when col = 0 then 1 else 0 end) > 0
then NULL
when mod(sum(sign(col)), 2) = 0
then exp(sum(ln(abs(col)))
else - exp(sum(ln(abs(col)))
end)
) as product
Проблемът е, че машината на базата данни може да получи грешка в регистрационния файл, преди да изпълни case
изявление. Така работи SQL Server. Не съм сигурен за Oracle.
А, това може да свърши работа:
select (case when sum(case when col = 0 then 1 else 0 end) > 0
then NULL
when mod(sum(sign(col)), 2) = 0
then exp(sum(ln(case when col <> 0 then abs(col) end)))
else - exp(sum(ln(case when col <> 0 then abs(col) end)))
end)
) as product
Връща NULL
когато има 0
.