Mysql
 sql >> Base de données >  >> RDS >> Mysql

Utilisation de MEDIAN avec les fonctions MAX, MIN et AVG dans MySQL

Vous pouvez calculer la médiane avec GROUP BY dans MySQL même s'il n'y a pas de fonction médiane intégrée.

Considérez le tableau :

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

Pour chaque ligne, vous pouvez compter le nombre d'éléments similaires qui sont inférieurs. Vous pouvez également compter le nombre de valeurs inférieures ou égales :

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

Avec requête

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

La valeur médiane se produit lorsque le nombre inférieur ou égal est égal à la moitié du nombre d'éléments

  • Acrington a 4 articles. La moitié de ceci est 2 qui est dans la gamme 0..2 (correspondant à 200.00) et aussi dans la gamme 2..3 (correspondant à 300.00)

  • Bullingdon a aussi 4 articles. 2 est compris entre 1..2 (valeur 300.00) et 2..3 (valeur 400.00)

  • Cardington a 5 articles. La valeur 2.5 est comprise entre 2 et 3 ce qui correspond à Cardington 151.

La valeur médiane est la moyenne des valeurs min et max renvoyées par :

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

Ce qui donne :

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

Enfin, nous pouvons obtenir la médiane :

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

Donner

Acrington   250.000000
Bulingdon   350.000000
Cardington  151.000000