sql >> Databasteknik >  >> RDS >> Mysql

Använda MEDIAN tillsammans med funktionerna MAX, MIN och AVG i MySQL

Du kan beräkna medianen med GROUP BY i MySQL även om det inte finns någon medianfunktion inbyggd.

Tänk på tabellen:

Acrington   200.00
Acrington   200.00
Acrington   300.00
Acrington   400.00
Bulingdon   200.00
Bulingdon   300.00
Bulingdon   400.00
Bulingdon   500.00
Cardington  100.00
Cardington  149.00
Cardington  151.00
Cardington  300.00
Cardington  300.00

För varje rad kan du räkna antalet liknande föremål som är färre. Du kan också räkna hur många värden som är mindre än eller lika med:

name        v       <   <=
Acrington   200.00  0   2
Acrington   200.00  0   2
Acrington   300.00  2   3
Acrington   400.00  3   4
Bulingdon   200.00  0   1
Bulingdon   300.00  1   2
Bulingdon   400.00  2   3
Bulingdon   500.00  3   4
Cardington  100.00  0   1
Cardington  149.00  1   2
Cardington  151.00  2   3
Cardington  300.00  3   5
Cardington  300.00  3   5

Med fråga

SELECT name,v, (SELECT COUNT(1) FROM sale WHERE v<o.v AND name=o.name) as ls
             , (SELECT COUNT(1) FROM sale WHERE v<=o.v AND name=o.name) as lse
  FROM sale o

Medianvärdet uppstår när antalet mindre än-eller-lika är hälften av antalet objekt

  • Acrington har 4 artiklar. Hälften av detta är 2 som ligger i intervallet 0..2 (motsvarande 200.00) och även i intervallet 2..3 (motsvarande 300.00)

  • Bullingdon har även 4 artiklar. 2 är i intervallet 1..2 (värde 300.00) och 2..3 (värde 400.00)

  • Cardington har 5 artiklar. Värdet 2,5 är mellan 2 och 3 vilket motsvarar Cardington 151.

Medianvärdet är medelvärdet av min- och maxvärdena som returneras av:

SELECT cs.name,v
   FROM
   (SELECT name,v, (SELECT COUNT(1) FROM sale WHERE v<o.v AND name=o.name) as ls
                 , (SELECT COUNT(1) FROM sale WHERE v<=o.v AND name=o.name) as lse
      FROM sale o) cs JOIN
   (SELECT name,COUNT(1)*.5 as cn
      FROM sale
      GROUP BY name) cc ON cs.name=cc.name
 WHERE cn between ls and lse

Vilket ger:

Acrington   200.00
Acrington   200.00
Acrington   300.00
Bulingdon   300.00
Bulingdon   400.00
Cardington  151.00

Äntligen kan vi få medianen:

SELECT name,(MAX(v)+MIN(v))/2 FROM
(SELECT cs.name,v
   FROM
   (SELECT name,v, (SELECT COUNT(1) FROM sale WHERE v<o.v AND name=o.name) as ls
                 , (SELECT COUNT(1) FROM sale WHERE v<=o.v AND name=o.name) as lse
      FROM sale o) cs JOIN
   (SELECT name,COUNT(1)*.5 as cn
      FROM sale
     GROUP BY name) cc ON cs.name=cc.name
 WHERE cn between ls and lse
 ) AS medians
GROUP BY name

Ge

Acrington   250.000000
Bulingdon   350.000000
Cardington  151.000000


  1. Hur hanterar man fel för dubbla poster?

  2. Det gick inte att läsa värdet för automatisk ökning från lagringsmotorn, felnummer:1467

  3. Hur man tar bort poster i DB med mySQL med hjälp av group by

  4. Distant HasManyThrough