クエリを使って行を列にしたい時がある。
例えば、ある分類の中の複数項目、生徒の教科別、商品分類など。
ただし、以下の方法は列にしたい項目が数十個になると面倒になる。
CASE WHENを使う方法とサブクエリを使う方法がある
成績表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
--行を列にする方法 --教科 SELECT * FROM ScoreRows /* 生徒単位で教科が複数存在する student_id subject score A001 英語 100 A001 国語 58 A001 数学 90 B002 英語 77 B002 国語 60 C003 英語 52 C003 国語 49 C003 社会 100 考え方は生徒を単位として、教科を列に置き換える。そして、Scoreを教科の列に入れる 従来はSubjectが教科だった。 */ --を使用する。 --(1)CASE文MAXを使って行を列にする。MAXがないと集計関数がないので --エラーになる。MINでもよくて1件出力することが大事 SELECT student_id, MAX(CASE WHEN subject = '英語'--subjectが英語のときにScoreを入れて列をEIGO THEN score END) AS EIGO,--ASにして教科を指定しているのでELSEはない。 MAX(CASE WHEN subject = '国語' THEN score END) AS KOKUGO, MAX(CASE WHEN subject = '数学' THEN score END) AS SUGAKU, MAX(CASE WHEN subject = '社会' THEN score END) AS SHAKAI FROM ScoreRows GROUP BY student_id--グループにして、MAXで取得するところがポイント --グループにすることで生徒一人の教科群を1行のまとまりととらえることができる。なので、横に列として出力できる。それがGroupの効果である。 --(2)サブクエリを使って行を列にする方法、結合INNERは使っていない。 --非効率とされる方法 SELECT student_id, (SELECT score FROM ScoreRows as sc --SELECTで条件を追加する WHERE subject='英語' and sc.student_id = sr.student_id) as EIGO, (SELECT score FROM ScoreRows as sc WHERE subject='国語' and sc.student_id = sr.student_id) as KOKUGO, (SELECT score FROM ScoreRows as sc WHERE subject='数学' and sc.student_id = sr.student_id) as SUGAKU, (SELECT score FROM ScoreRows as sc WHERE subject='社会' and sc.student_id = sr.student_id) as SHAKAI From ScoreRows as sr GROUP by student_id |