Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Função agregada Product()


A abordagem logaratmo/potência é a abordagem geralmente usada. Para Oracle, isto é:
select exp(sum(ln(col)))
from table;

Não sei por que os designers de banco de dados originais não incluíram PRODUCT() como uma função de agregação. Meu melhor palpite é que eles eram todos cientistas da computação, sem estatísticos. Essas funções são muito úteis em estatística, mas não aparecem muito em ciência da computação. Talvez eles não quisessem lidar com problemas de estouro, que tal função implicaria (especialmente em números inteiros).

A propósito, essa função está ausente na maioria dos bancos de dados, mesmo naqueles que implementam muitas funções de agregação estatística.

editar:

Oi, o problema dos números negativos complica um pouco:
select ((case when mod(sum(sign(col)), 2) = 0 then 1 else -1 end) *
        exp(sum(ln(abs(col))))
       ) as product

Não tenho certeza de uma maneira segura no Oracle para lidar com 0 s. Esta é uma abordagem "lógica":
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

O problema é que o mecanismo de banco de dados pode receber um erro no log antes de executar o case declaração. É assim que o SQL Server funciona. Não tenho certeza sobre a Oracle.

Ah, isso pode funcionar:
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

Ele retorna NULL quando há um 0 .