MUL máte na mysli progresivní násobení hodnot?
I se 100 řádky nějaké malé velikosti (řekněme 10 s) váš MUL (sloupec) přeteče jakýkoli datový typ! S tak vysokou pravděpodobností nesprávného/nesprávného použití a velmi omezeným rozsahem použití to nemusí být standard SQL. Jak ukázali jiní, existují matematické způsoby, jak to vyřešit, stejně jako existuje mnoho způsobů, jak provádět složité výpočty v SQL pouze pomocí standardních (a běžně používaných) metod.
Ukázková data:
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 )
Pro úplnost, základní implementace 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)))
- Při používání EXP/LOG v SQL Server buďte opatrní, sledujte návratový typ http://msdn.microsoft.com/en-us/library/ms187592.aspx
- Formát POWER umožňuje větší čísla (pomocí základen větších než Eulerovo číslo) a v případech, kdy je výsledek příliš velký na to, aby jej mohl vrátit pomocí POWER, můžete vrátit pouze logaritmickou hodnotu a vypočítat skutečné číslo mimo SQL dotaz
* LOG(0) a LOG(-ve) nejsou definovány. Níže uvedené pouze ukazuje, jak to zvládnout v SQL Server. Ekvivalenty lze nalézt pro ostatní příchutě SQL pomocí stejného konceptu
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
Ingredience:
- při použití abs() dat, pokud je min. 0, násobení čímkoli jiným je marné, výsledek je 0
- Pokud jsou data 0, NULLIF je převede na hodnotu null. Obě abs(), log() vrátí hodnotu null, což způsobí, že bude vyloučeno ze sum()
- Pokud data nejsou 0, abs nám umožňuje vynásobit záporné číslo pomocí metody LOG – budeme sledovat negativitu jinde
- Vypracování konečného znaku
- sign(data) vrací
1 for >0
,0 for 0
a-1 for <0
. - Přidáme další 0,5 a znovu vezmeme znaménko(), takže jsme nyní klasifikovali 0 a 1 obě jako 1 a pouze -1 jako -1.
- znovu použijte NULLIF k odstranění jedniček z COUNT(), protože potřebujeme spočítat pouze záporná čísla.
% 2
proti count() záporných čísel vrátí buď- --> 1, pokud existuje lichý počet záporných čísel
- --> 0, pokud existuje sudý počet záporných čísel
- více matematických triků:ubereme 1 nebo 0 z 0,5, takže výše uvedené bude
- --> (
0.5-1=-0.5
=>zaokrouhlit na -1 ) pokud existuje lichý počet záporných čísel - --> (
0.5-0= 0.5
=>zaokrouhlit na 1 ) pokud existuje sudý počet záporných čísel - vynásobíme tuto konečnou 1/-1 oproti hodnotě SUM-PRODUCT pro skutečný výsledek
- sign(data) vrací