LoginSignup
1
0

More than 1 year has passed since last update.

MySQLで中央値を取得するおそらく最も簡単な方法

Last updated at Posted at 2022-09-17

今回は目次なしで一気に―――

MySQLには中央値を算出するための集約関数が存在しないということを、驚きをもってひしひしと受け止めた後は、
1. MariaDBの10.3.3以上を使う
2. ユーザー定義変数を使って自前で真ん中の行を取得する
3. 先人の遺したカスタム集約関数でmedianをgcc経由でデプロイする
等で対策していくことになりますが、

  • 1は、medianが使いたいからアップグレードする、というような条件反射が効くプロトタイプやスタートアップならともかく、普通はセキュリティポリシーやリプレース等での計画が先にあって、その中でエンジニアは頑張るのかと思います。
  • 2は、すでにあちこちにSQLが存在する既存システムではマイグレーションが大変です。
  • 3は、残念ながらもう15年以上前の化石的遺産なので、パッチ充てどころかデグレードまで必要になってきます。

というわけで、これらを踏まえて今 MySQLで中央値を取得するおそらく最も簡単な方法 は、以下になるのではないかと思います。

infusion/udf_infusion: A MySQL functionality enhancement UDF

cd /usr/local/src/
git clone https://github.com/infusion/udf_infusion.git
cd udf_infusion
./configure --enable-functions="median"
make
sudo make install
cat ./load.sql
    DROP FUNCTION IF EXISTS median;
    CREATE AGGREGATE FUNCTION median RETURNS real SONAME 'udf_infusion.so';

sudo find /usr/lib* -name udf_infusion.so
    /usr/lib64/mysql/plugin/udf_infusion.so

mysql testdb -u testuser -p < ./load.sql

mysql testdb -u testuser -p
    SELECT MEDIAN(cnt), AVG(cnt) FROM (
      SELECT 0 AS cnt
      UNION ALL
      SELECT 0 AS cnt
      UNION ALL
      SELECT 1 AS cnt
      UNION ALL
      SELECT 2 AS cnt
      UNION ALL
      SELECT 8 AS cnt
      UNION ALL
      SELECT 9 AS cnt
      UNION ALL
      SELECT 9 AS cnt
    ) mix;
        +-------------+----------+
        | MEDIAN(cnt) | AVG(cnt) |
        +-------------+----------+
        |           2 |   4.1429 |
        +-------------+----------+

確認環境: CentOS7.4 + MySQL5.7.36

簡単ですね。
まだQiitaで拾われていないようなのでご紹介まで。

ここでは --enable-functions="median" と、中央値を取得するための関数しか入れていませんが、他にも最頻値を取得したり、文字列操作用の関数があったりと、いろいろと楽しく頑張れそうです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0