ある学校の、生徒の名前と、その所属クラスを記入した、以下のようなテーブルがあるとします。なお、これらのデータは擬似個人情報データ生成サービスにより出力されたもので、全て架空です。
mysql> SELECT * FROM students;
+-----+---------------------+---------------------------------+---------------------+----------+
| id | name | kana | roman | class_id |
+-----+---------------------+---------------------------------+---------------------+----------+
| 1 | 大森 比呂美 | オオモリ ヒロミ | Oomori Hiromi | 1 |
| 2 | 長野 紗矢 | ナガノ サヤ | Nagano Saya | 1 |
| 3 | 杉浦 円 | スギウラ マドカ | Sugiura Madoka | 1 |
~~~
| 198 | 寺本 禎 | テラモト タダシ | Teramoto Tadashi | 5 |
| 199 | 高橋 満雄 | タカハシ ミツオ | Takahashi Mitsuo | 5 |
| 200 | 柴山 謙一 | シバヤマ ケンイチ | Shibayama Kenichi | 5 |
+-----+---------------------+---------------------------------+---------------------+----------+
200 rows in set (0.00 sec)
5 クラスあり、どのクラスも 40 名、総勢 200 名の学校です。
さて、それぞれのクラスから 1 名ずつ、学級委員長を選出するとします。当然立候補者はおらず、推薦のなすりつけ合いになることでしょう。そこで、全クラスとも、抽選で学級委員を選出することになりました。
それぞれのクラスでクジを作るのもいい考えですが、我々エンジニアは、MySQL によるソリューションを行うべきでしょう。というわけで以下の SQL を実行。
SELECT
class_id,
SUBSTRING_INDEX(GROUP_CONCAT(name ORDER BY RAND()), ',', 1) AS name
FROM
students
GROUP BY
class_id
この SQL から得られる結果は以下の通り。
+----------+---------------+
| class_id | name |
+----------+---------------+
| 1 | 戸田 有沙 |
| 2 | 大森 一行 |
| 3 | 金山 清志 |
| 4 | 藤木 啓一 |
| 5 | 岩渕 雅彦 |
+----------+---------------+
5 rows in set (0.00 sec)
そして、この SQL は、常にランダムな抽出を行うので、当然結果は毎回異なります。例えば以下のように。
+----------+---------------+
| class_id | name |
+----------+---------------+
| 1 | 高見 幸子 |
| 2 | 森川 里菜 |
| 3 | 塩崎 凛乃 |
| 4 | 高畑 栄三 |
| 5 | 柴山 謙一 |
+----------+---------------+
5 rows in set (0.00 sec)
また、選出された学級委員の名前だけではなく、生徒番号やフリガナ等の情報も紐付ける必要がある場合は、以下のように少々複雑になります。自己結合を使います。
SELECT
sub.class_id,
sub.student_id,
students.name,
students.kana,
students.roman
FROM
(
SELECT
class_id,
SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY RAND()), ',', 1) AS student_id
FROM
students
GROUP BY
class_id
) AS sub
LEFT JOIN
students
ON
sub.student_id = students.id
+----------+------------+------------------+------------------------------+-------------------+
| class_id | student_id | name | kana | roman |
+----------+------------+------------------+------------------------------+-------------------+
| 1 | 32 | 湯川 信明 | ユカワ ノブアキ | Yukawa Nobuaki |
| 2 | 78 | 金丸 紗良 | カナマル サラ | Kanamaru Sara |
| 3 | 111 | 熊倉 美千子 | クマクラ ミチコ | Kumakura Michiko |
| 4 | 150 | 吉田 長次郎 | ヨシダ チョウジロウ | Yoshida Choujirou |
| 5 | 167 | 日比野 善之 | ヒビノ ヨシユキ | Hibino Yoshiyuki |
+----------+------------+------------------+------------------------------+-------------------+
5 rows in set (0.00 sec)
この抽選作業を MySQL で実現する上で、あまり日の当たらない (と、少なくとも私は考えている) 関数が 2 つほど活躍しています。それらについてはまたの機会に紹介しようと思っています。こんな、MySQL クックブックの隅にも載らないような SQL は何人の役に立つかはわかりませんが、GROUP_CONCAT は意外とできる子なので、皆さんも是非使ってみてください。
MySQL