Przez MUL masz na myśli progresywne mnożenie wartości?
Nawet przy 100 wierszach o jakimś małym rozmiarze (powiedzmy 10s), Twój MUL(kolumna) przepełni dowolny typ danych! Przy tak dużym prawdopodobieństwie niewłaściwego/nadużywania i bardzo ograniczonym zakresie użycia, nie musi to być standard SQL. Jak pokazali inni, istnieją matematyczne sposoby rozwiązania tego problemu, podobnie jak istnieje wiele sposobów wykonywania skomplikowanych obliczeń w SQL przy użyciu standardowych (i powszechnie używanych) metod.
Przykładowe dane:
Column
1
2
4
8
COUNT : 4 items (1 for each non-null)
SUM : 1 + 2 + 4 + 8 = 15
AVG : 3.75 (SUM/COUNT)
MUL : 1 x 2 x 4 x 8 ? ( =64 )
Aby uzyskać kompletność, podstawowe implementacje Oracle, MSSQL, MySQL *
Oracle : EXP(SUM(LN(column))) or POWER(N,SUM(LOG(column, N)))
MSSQL : EXP(SUM(LOG(column))) or POWER(N,SUM(LOG(column)/LOG(N)))
MySQL : EXP(SUM(LOG(column))) or POW(N,SUM(LOG(N,column)))
- Uważaj podczas używania EXP/LOG w SQL Server, obserwuj typ zwracany http://msdn.microsoft.com/en-us/library/ms187592.aspx
- Forma POTĘGA pozwala na większe liczby (przy użyciu podstaw większych niż liczba Eulera), a w przypadkach, gdy wynik jest zbyt duży, aby odwrócić go za pomocą POTĘGI, możesz zwrócić tylko wartość logarytmiczną i obliczyć rzeczywistą liczbę poza Zapytanie SQL
* LOG(0) i LOG(-ve) są niezdefiniowane. Poniżej pokazano tylko, jak sobie z tym poradzić w SQL Server. Odpowiedniki można znaleźć dla innych smaków SQL, korzystając z tej samej koncepcji
create table MUL(data int)
insert MUL select 1 yourColumn union all
select 2 union all
select 4 union all
select 8 union all
select -2 union all
select 0
select CASE WHEN MIN(abs(data)) = 0 then 0 ELSE
EXP(SUM(Log(abs(nullif(data,0))))) -- the base mathematics
* round(0.5-count(nullif(sign(sign(data)+0.5),1))%2,0) -- pairs up negatives
END
from MUL
Składniki:
- biorąc abs() danych, jeśli min wynosi 0, pomnożenie przez cokolwiek innego jest daremne, wynik wynosi 0
- Kiedy dane są równe 0, NULLIF konwertuje je na null. Abs(), log() zwracają wartość null, powodując wykluczenie z sum()
- Jeśli dane nie są równe 0, abs pozwala nam pomnożyć liczbę ujemną przy użyciu metody LOG - będziemy śledzić ujemność gdzie indziej
- Opracowanie ostatecznego znaku
- znak(dane) zwraca
1 for >0
,0 for 0
i-1 for <0
. - Dodajemy kolejne 0,5 i ponownie przyjmujemy znak(), więc teraz sklasyfikowaliśmy 0 i 1 jako 1, a tylko -1 jako -1.
- ponownie użyj NULLIF, aby usunąć z COUNT() jedynki, ponieważ musimy tylko policzyć negatywy.
% 2
w stosunku do count() liczb ujemnych zwraca albo- --> 1, jeśli istnieje nieparzysta liczba liczb ujemnych
- --> 0, jeśli liczba liczb ujemnych jest parzysta
- więcej sztuczek matematycznych:bierzemy 1 lub 0 z 0,5, aby powyższe stało się
- --> (
0.5-1=-0.5
=>zaokrąglaj do -1 ) jeśli istnieje nieparzysta liczba liczb ujemnych - --> (
0.5-0= 0.5
=>zaokrąglaj do 1 ) jeśli jest parzysta liczba liczb ujemnych - mnożymy tę końcową 1/-1 przez wartość SUM-PRODUCT, aby uzyskać rzeczywisty wynik
- znak(dane) zwraca