Podejście logarytmiczne/potęgowe jest powszechnie stosowanym podejściem. W przypadku Oracle jest to:
select exp(sum(ln(col)))
from table;
Nie wiem, dlaczego oryginalni projektanci baz danych nie uwzględnili PRODUCT()
jako funkcja agregacji. Domyślam się, że wszyscy byli informatykami, bez statystyków. Takie funkcje są bardzo przydatne w statystyce, ale nie pojawiają się zbyt często w informatyce. Być może nie chcieli zajmować się problemami przepełnienia, które taka funkcja by implikowała (zwłaszcza na liczbach całkowitych).
Nawiasem mówiąc, tej funkcji brakuje w większości baz danych, nawet tych, które implementują wiele funkcji agregacji statystycznych.
edytuj:
Oj, problem liczb ujemnych trochę go komplikuje:
select ((case when mod(sum(sign(col)), 2) = 0 then 1 else -1 end) *
exp(sum(ln(abs(col))))
) as product
Nie jestem pewien bezpiecznego sposobu w Oracle na obsługę 0
s. To jest „logiczne” podejście:
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
Problem polega na tym, że silnik bazy danych może otrzymać błąd w dzienniku przed wykonaniem case
oświadczenie. Tak właśnie działa SQL Server. Nie jestem pewien co do Oracle.
Ach, to może zadziałać:
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
Zwraca NULL
gdy jest 0
.