L'approche logarathme/puissance est l'approche généralement utilisée. Pour Oracle, c'est :
select exp(sum(ln(col)))
from table;
Je ne sais pas pourquoi les concepteurs de la base de données d'origine n'ont pas inclus PRODUCT()
comme fonction d'agrégation. Ma meilleure supposition est qu'ils étaient tous des informaticiens, sans statisticiens. De telles fonctions sont très utiles en statistique, mais elles n'apparaissent pas beaucoup en informatique. Peut-être ne voulaient-ils pas traiter les problèmes de débordement, qu'une telle fonction impliquerait (surtout sur les entiers).
Soit dit en passant, cette fonction est absente de la plupart des bases de données, même celles qui implémentent de nombreuses fonctions d'agrégation statistiques.
modifier :
Oy, le problème des nombres négatifs rend les choses un peu plus compliquées :
select ((case when mod(sum(sign(col)), 2) = 0 then 1 else -1 end) *
exp(sum(ln(abs(col))))
) as product
Je ne suis pas sûr d'un moyen sûr dans Oracle pour gérer 0
s. C'est une approche "logique":
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
Le problème est que le moteur de base de données peut obtenir une erreur sur le journal avant d'exécuter le case
déclaration. C'est ainsi que fonctionne SQL Server. Je ne suis pas sûr d'Oracle.
Ah, ça pourrait marcher :
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
Il renvoie NULL
quand il y a un 0
.