勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

MySQLで指定したカラムの中央値を抽出する方法

  MySQL データベース

MySQLで指定したカラムの中央値を抽出したいというケースがあった。MariaDBの10.3.3以上だと中央値を求めるMEDIAN()という関数が実装されているらしいが、当方の環境はMySQL8.0.32のため実装されておらず、SQL文で何とかしないといけないっぽい。以下に対応方法をメモ。

 

テーブル構造

mysql> SHOW COLUMNS FROM `test_table`;
+-------+------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra          |
+-------+------+------+-----+---------+----------------+
| id    | int  | NO   | PRI | NULL    | auto_increment |
| score | int  | NO   |     | NULL    |                |
+-------+------+------+-----+---------+----------------+

 

データ内容

mysql> SELECT * FROM `test_table` ORDER BY `score` DESC;
+----+-------+
| id | score |
+----+-------+
|  1 |   100 |
|  4 |    80 |
|  5 |    70 |
| 10 |    70 |
|  3 |    60 |
|  7 |    55 |
|  6 |    50 |
|  2 |    40 |
|  8 |    20 |
|  9 |    20 |
+----+-------+

 

対応方法

SQL文

SET @row_index := -1;
SELECT AVG(subq.score) AS median_value 
FROM 
    (
        SELECT @row_index:=@row_index + 1 AS row_index, score
        FROM test_table
        ORDER BY score
    ) AS subq
WHERE subq.row_index IN (FLOOR(@row_index / 2), CEIL(@row_index / 2));

出力結果

上記SQL文を実行すると以下が出力される筈。全データの行数が偶数になるため、id3の60とid7の50の平均値が出力される。

+--------------+
| median_value |
+--------------+
|      57.5000 |
+--------------+

全データの行数が奇数の場合

以下のように全データの行数が奇数行の場合、

mysql> SELECT * FROM `test_table` ORDER BY `score` DESC;
+----+-------+
| id | score |
+----+-------+
|  1 |   100 |
|  4 |    80 |
|  5 |    70 |
| 10 |    70 |
|  3 |    60 |
|  7 |    55 |
|  6 |    50 |
|  2 |    40 |
| 11 |    30 |
|  8 |    20 |
|  9 |    20 |
+----+-------+

前述のSQL文を実行すると以下が出力される筈。

+--------------+
| median_value |
+--------------+
|      55.0000 |
+--------------+

こちらはid7の55がそのまま出力された。

 

参考サイト

https://sebhastian.com/mysql-median/

 - MySQL データベース

  関連記事

MySQLにて指定したカラムがNULLもしくは空の場合、あらかじめ決めておいた内容で表示する方法

何らかのフォームとMySQLを組み合わせた際に任意入力の項目はそのカラムがNUL ...

MySQLで「server has gone~」というエラーの対応方法

MySQLで「MySQL server has gone away」というエラー ...

SQLで同じ値を複数のレコードに対してUPDATE

やりたかった事は、複数のレコードに対して 同じ値に更新したいというもの。 $sq ...

MySQLでtext型カラムに入っている数値をint型としてソートする

MySQLでtext型として指定されているカラムがあり、その中には文字列であった ...

MySQLで特定カラムの
タグを改行コードに一括置換させる方法

MySQLで特定カラムの<br>タグを改行コードに一括置換したかった ...