sql >> Databáze >  >> RDS >> Sqlserver

Multiplikační agregační operátor v SQL

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


  1. Vložte více záznamů do oracle

  2. PostgreSQL:Fulltextové vyhledávání - Jak hledat dílčí slova?

  3. Použití SQL Server Profiler | Řešení problémů s výkonem serveru SQL -5

  4. ST_DWithin bere parametr jako stupeň, ne metry, proč?