Logarathme/power-tilgangen er den almindeligt anvendte tilgang. For Oracle er det:
select exp(sum(ln(col)))
from table;
Jeg ved ikke, hvorfor de oprindelige databasedesignere ikke inkluderede PRODUCT()
som en aggregeringsfunktion. Mit bedste gæt er, at de alle var dataloger uden statistikere. Sådanne funktioner er meget nyttige i statistik, men de vises ikke meget i datalogi. Måske ønskede de ikke at beskæftige sig med overløbsproblemer, som en sådan funktion ville indebære (især på heltal).
Denne funktion mangler i øvrigt i de fleste databaser, selv dem, der implementerer mange statistiske aggregeringsfunktioner.
rediger:
Åh, problemet med negative tal gør det lidt mere kompliceret:
select ((case when mod(sum(sign(col)), 2) = 0 then 1 else -1 end) *
exp(sum(ln(abs(col))))
) as product
Jeg er ikke sikker på en sikker måde i Oracle at håndtere 0
på s. Dette er en "logisk" tilgang:
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
Problemet er, at databasemotoren muligvis får en fejl i loggen, før den udfører case
udmelding. Det er tilfældigvis sådan, SQL Server fungerer. Jeg er ikke sikker på Oracle.
Ah, det kan måske virke:
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
Det returnerer NULL
når der er en 0
.