Oracle
 sql >> Base de données >  >> RDS >> Oracle

Fonction d'agrégation Product()

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 .