sql >> Databasteknik >  >> RDS >> Sqlserver

Multiplikationsaggregatoperator i SQL

Med MUL menar du progressiv multiplikation av värden?

Även med 100 rader av någon liten storlek (säg 10s), kommer din MUL(kolumn) att svämma över vilken datatyp som helst! Med en så hög sannolikhet för missbruk/missbruk, och mycket begränsat utrymme för användning, behöver det inte vara en SQL-standard. Som andra har visat finns det matematiska sätt att räkna ut det, precis som det finns många många sätt att göra knepiga beräkningar i SQL bara med standardmetoder (och vanliga metoder).

Exempeldata:

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 )

För fullständighetens skull, Oracle, MSSQL, MySQL kärnimplementeringar *

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)))
  • Var försiktig när du använder EXP/LOG i SQL Server, titta på returtypen http://msdn.microsoft.com/en-us/library/ms187592.aspx
  • POWER-formuläret tillåter större tal (med baser större än Eulers tal), och i de fall där resultatet blir för stort för att vända tillbaka det med POWER, kan du returnera bara det logaritmiska värdet och beräkna det faktiska talet utanför SQL-fråga

* LOG(0) och LOG(-ve) är odefinierade. Nedanstående visar bara hur man hanterar detta i SQL Server. Motsvarigheter kan hittas för de andra SQL-smakerna, med samma koncept

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

Ingredienser:

  • om man tar abs() för data, om min är 0, multiplicera med allt annat som är meningslöst, blir resultatet 0
  • När data är 0, konverterar NULLIF den till null. Abs(), log() returnerar båda null, vilket gör att den utesluts från sum()
  • Om data inte är 0, tillåter abs oss att multiplicera ett negativt tal med LOG-metoden - vi kommer att hålla reda på negativiteten någon annanstans
  • Tränar ut det sista tecknet
    • tecken(data) returnerar 1 for >0 , 0 for 0 och -1 for <0 .
    • Vi lägger till ytterligare 0,5 och tar tecknet() igen, så vi har nu klassificerat 0 och 1 både som 1 och bara -1 som -1.
    • använd återigen NULLIF för att ta bort 1:orna från COUNT() eftersom vi bara behöver räkna upp negativen.
    • % 2 mot count() av ​​negativa tal returnerar antingen
    • --> 1 om det finns ett udda antal negativa tal
    • --> 0 om det finns ett jämnt antal negativa tal
    • fler matematiska knep:vi tar 1 eller 0 av 0,5, så att ovanstående blir
    • --> (0.5-1=-0.5 =>runda till -1 ) om det finns ett udda antal negativa tal
    • --> (0.5-0= 0.5 =>runda till 1 ) om det finns ett jämnt antal negativa tal
    • vi multiplicerar denna sista 1/-1 mot SUM-PRODUCT-värdet för det verkliga resultatet


  1. importera en CSV till phpmyadmin

  2. Hur man komprimerar och reparerar en databas automatiskt i Access 2016

  3. Anropa en Oracle-funktion från Java

  4. SqlConnection.Close() inuti med hjälp av satsen