SQL Serverにて取得したデータのたて持ち/よこ持ちを変換したいことが稀に良くあります。
メモとしてここに記しておきます。
目次
たて持ち→よこ持ち に変換
以下のようなデータがあります。
| ID | NAME |
|---|---|
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
これを⇩のように、よこ持ちに変換したい
| NAME1 | NAME2 | NAME3 | NAME4 |
|---|---|---|---|
| A | B | C | D |
この場合、以下のように記述します。
SELECT
MAX(CASE WHEN ID = 1 THEN NAME END) AS NAME1,
MAX(CASE WHEN ID = 2 THEN NAME END) AS NAME2,
MAX(CASE WHEN ID = 3 THEN NAME END) AS NAME3,
MAX(CASE WHEN ID = 4 THEN NAME END) AS NAME4
FROM
TABLEよこ持ち→たて持ち に変換
以下のようなデータがあります。
| ID | NAME1 | NAME2 | NAME3 | NAME4 |
|---|---|---|---|---|
| 1 | A | B | C | D |
これを⇩のように、たて持ちに変換したい
| NAME |
|---|
| A |
| B |
| C |
| D |
この場合、以下のように記述します。
SELECT NAME1 FROM TABLE WHERE ID = 1
UNION
SELECT NAME2 FROM TABLE WHERE ID = 1
UNION
SELECT NAME3 FROM TABLE WHERE ID = 1
UNION
SELECT NAME4 FROM TABLE WHERE ID = 1解説
見ればわかる人にはわかると思うので不要かもしれませんが一応解説。
たて持ち→よこ持ちの解説
| ID | NAME |
|---|---|
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
たて持ち→よこ持ちの変換はCASE式とMAXを併用しています。
まず
・ID=1のA
・ID=2のB
・ID=3のC
・ID=4のD
これをそれぞれ別カラムに分けたいのでCASE式で分割します。
SELECT
CASE WHEN ID = 1 THEN NAME END AS NAME1,
CASE WHEN ID = 2 THEN NAME END AS NAME2,
CASE WHEN ID = 3 THEN NAME END AS NAME3,
CASE WHEN ID = 4 THEN NAME END AS NAME4
FROM
TABLEすると結果はこうなります。
| NAME1 | NAME2 | NAME3 | NAME4 |
|---|---|---|---|
| A | NULL | NULL | NULL |
| NULL | B | NULL | NULL |
| NULL | NULL | C | NULL |
| NULL | NULL | NULL | D |
取得結果が4件になるので、当然このような結果になります。
指定したIDだった場合はNAMEが取得されて、それ以外の場合はNULLになります。
後はこれをギュッと1行にまとめたいのですが、そこで集計関数のMAXを使います。
SELECT
MAX(CASE WHEN ID = 1 THEN NAME END) AS NAME1,
MAX(CASE WHEN ID = 2 THEN NAME END) AS NAME2,
MAX(CASE WHEN ID = 3 THEN NAME END) AS NAME3,
MAX(CASE WHEN ID = 4 THEN NAME END) AS NAME4
FROM
TABLE列ごとに見ると、NULLか”A”or”B”or”C”or”D”が存在しているので、MAXを取ると必ずNULLじゃない方の値が取得されて、1行に集約されます。
| NAME1 | NAME2 | NAME3 | NAME4 |
|---|---|---|---|
| A | B | C | D |
GROUP BY句を使っていないのに、MAXを取ってこうなるっていうのは直感的に違和感がある人もいるかもしれないですけど、MAXはこのような挙動をとるということですね。
間違えてここに「GROUP BY NAME」をつけると、MAXを使わなかったときと同じ結果になります。A,B,C,Dがそれぞれ別の値だからグルーピングされなくなるということですね。あくまでCASE式の結果に対してMAXを取るというところが重要です。
MySQLとかポスグレの集計関数は若干挙動が違うといううわさがあるので、気になった方はやってみるといいかもしれません。
でも多分一緒になってくれるはずです。
よこ持ち→たて持ち の解説
これはもはや解説不要ですね。
AだけとるSQL、BだけとるSQL、CだけとるSQL、DだけとるSQL・・・
といった具合に列ごとに取得するSQLを分けてUNIONでくっ付けただけです。
オススメのSQL学習本
初心者向けのオススメのSQLの学習本です。
以下にまとめてみたので参考にどうぞ。




最近のコメント