Mysql
 sql >> Database >  >> RDS >> Mysql

Utilizzo di MEDIAN insieme alle funzioni MAX, MIN e AVG in MySQL

Puoi calcolare la mediana con GROUP BY in MySQL anche se non esiste una funzione mediana incorporata.

Considera la tabella:

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

Per ogni riga puoi contare il numero di elementi simili che sono inferiori. Puoi anche contare quanti valori sono minori o uguali:

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

Con richiesta

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

Il valore mediano si verificherà quando il conteggio minore o uguale è la metà del numero di elementi

  • Acrington ha 4 articoli. La metà di questo è 2 che è nell'intervallo 0..2 (corrispondente a 200.00) e anche nell'intervallo 2..3 (corrispondente a 300.00)

  • Bullingdon ha anche 4 articoli. 2 è compreso tra 1..2 (valore 300.00) e 2..3 (valore 400.00)

  • Cardington ha 5 articoli. Il valore 2,5 è compreso tra 2 e 3 che corrisponde a Cardington 151.

Il valore mediano è la media dei valori minimo e massimo restituiti da:

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

Che dà:

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

Finalmente possiamo ottenere la mediana:

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

Dare

Acrington   250.000000
Bulingdon   350.000000
Cardington  151.000000