Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Aggregatfunktion Product()

Der Logarithmus/Potenz-Ansatz ist der allgemein verwendete Ansatz. Für Oracle ist das:

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

Ich weiß nicht, warum die ursprünglichen Datenbankdesigner PRODUCT() nicht einbezogen haben als Aggregationsfunktion. Meine beste Vermutung ist, dass sie alle Informatiker waren, ohne Statistiker. Solche Funktionen sind in der Statistik sehr nützlich, aber in der Informatik kommen sie nicht oft vor. Vielleicht wollten sie sich nicht mit Überlaufproblemen befassen, die eine solche Funktion implizieren würde (insbesondere bei Ganzzahlen).

Diese Funktion fehlt übrigens bei den meisten Datenbanken, auch bei denen, die viele statistische Aggregationsfunktionen implementieren.

Bearbeiten:

Oy, das Problem der negativen Zahlen macht es etwas komplizierter:

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

Ich bin mir nicht sicher, ob ich in Oracle sicher mit 0 umgehen kann s. Dies ist ein "logischer" Ansatz:

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

Das Problem ist, dass die Datenbank-Engine möglicherweise einen Fehler im Protokoll erhält, bevor sie den case ausführt Aussage. So funktioniert SQL Server. Bei Oracle bin ich mir nicht sicher.

Ah, das könnte funktionieren:

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

Es gibt NULL zurück wenn es eine 0 gibt .