Oracle
 sql >> Database >  >> RDS >> Oracle

Product() funzione di aggregazione

L'approccio logaritmico/potenza è l'approccio generalmente utilizzato. Per Oracle, ovvero:

select exp(sum(ln(col)))
from table;

Non so perché i progettisti di database originali non includessero PRODUCT() come funzione di aggregazione. La mia ipotesi migliore è che fossero tutti informatici, senza statistici. Tali funzioni sono molto utili in statistica, ma non si vedono molto in informatica. Forse non volevano affrontare i problemi di overflow, che una tale funzione implicherebbe (soprattutto sugli interi).

A proposito, questa funzione manca nella maggior parte dei database, anche in quelli che implementano molte funzioni di aggregazione statistica.

modifica:

Ehi, il problema dei numeri negativi lo rende un po' più complicato:

select ((case when mod(sum(sign(col)), 2) = 0 then 1 else -1 end) *
        exp(sum(ln(abs(col))))
       ) as product

Non sono sicuro di un modo sicuro in Oracle per gestire 0 S. Questo è un approccio "logico":

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

Il problema è che il motore di database potrebbe ricevere un errore nel registro prima di eseguire il case dichiarazione. Questo è il modo in cui funziona SQL Server. Non sono sicuro di Oracle.

Ah, questo potrebbe funzionare:

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

Restituisce NULL quando è presente un 0 .