結論だけ示します。
sql
1select kamoku,count(id) as kaisuu from (
2select id,substring_index(tag,',',1) as kamoku from post
3union select id,substring_index(substring_index(tag,',',2),',',-1) as kamoku from post
4union select id,substring_index(substring_index(tag,',',3),',',-1) as kamoku from post
5union select id,substring_index(substring_index(tag,',',4),',',-1) as kamoku from post
6union select id,substring_index(substring_index(tag,',',5),',',-1) as kamoku from post
7) as test group by kamoku order by kaisuu desc;
これの出力を以下に示します。
+--------+--------+
| kamoku | kaisuu |
+--------+--------+
| 算数 | 4 |
| 英語 | 3 |
| 国語 | 2 |
| 理科 | 1 |
+--------+--------+
4 rows in set (0.00 sec)
SQLを組み立てたときの思考回路
まず、科目とidの表がほしいと考えます。(擬似的に「第1正規形」に変換します)(第1正規形はデータベースの分野の専門用語です)
substring_indexを使うことでできることがわかりました。使い方は下の参考URLを見てください。
unionから始まる行がカンマ区切りで書かれる科目の個数分必要です。10科目書かれるなら10行必要です。行の中央付近で行ごとに2,3,4,5と増えているところをunionの行を増やして2,3,4,5,6,7,8,9,10とする必要があります。
sql
1select id,substring_index(tag,',',1) as kamoku from post
2union select id,substring_index(substring_index(tag,',',2),',',-1) as kamoku from post
3union select id,substring_index(substring_index(tag,',',3),',',-1) as kamoku from post
4union select id,substring_index(substring_index(tag,',',4),',',-1) as kamoku from post
5union select id,substring_index(substring_index(tag,',',5),',',-1) as kamoku from post;
下のような結果が得られます。
+----+--------+
| id | kamoku |
+----+--------+
| 1 | 国語 |
| 2 | 国語 |
| 3 | 算数 |
| 4 | 算数 |
| 5 | 英語 |
| 1 | 算数 |
| 2 | 算数 |
| 4 | 英語 |
| 2 | 理科 |
| 2 | 英語 |
+----+--------+
10 rows in set (0.00 sec)
あとはkamokuの出現数を求めるだけです。この表をfrom句に入れます(asで別名をつけないと怒られるのでas testってつけました。
sql
1select kamoku,count(id) as kaisuu from (ここに入れる) as test group by kamoku order by kaisuu desc;
そうすると最初に書いた結論の通りのSQL文になり、結果が出ます。
参考URL:
カンマ区切りの文字を分割する方法を調べた
この質問のコードがあった
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/08/05 16:10
2021/08/05 16:20
2021/08/05 19:51