こんにちは!ぽこです。
今回は、SQLでデータを横に並べる方法についてです。横一列にするのではなく、ある条件で横に並べていきます。
変換イメージ
今回紹介する変換は、次のような場合に使うことができます。
例として、学校を考えます。
元データ:純粋に生徒を並べたデータ
学年 | クラス | 名前 |
1 | 1 | 生徒A |
2 | 1 | 生徒B |
3 | 2 | 生徒C |
1 | 2 | 生徒D |
2 | 1 | 生徒E |
3 | 1 | 生徒F |
1 | 2 | 生徒G |
1 | 2 | 生徒H |
2 | 2 | 生徒I |
変換後データ:学年ごと、クラスごとに分けたデータ
1組 | 2組 | ||
学年 | 出席番号 | 名前 | 名前 |
1 | 1 | 生徒A | 生徒D |
1 | 2 | NULL | 生徒G |
1 | 3 | NULL | 生徒H |
2 | 1 | 生徒B | 生徒I |
2 | 2 | 生徒E | NULL |
3 | 1 | 生徒F | 生徒C |
このように、縦に学年、横にクラスという形で並べ替えます。
また、学年ごとになるように、空いている名前にはNULLが入ります。
コード
まず、次のようにして定数を定義します。
1 2 |
set @rownum_AA=0; set @rownum_BB=0; |
ここで、@rownum_AAが1列目(1組)、@rownum_BBが2列目(2組)の番号になります。この定数を使って、次のようなSQLを実行します。
1 2 3 4 5 6 7 8 9 10 11 |
select col1, rownum, AA.col3 as col3_AA, BB.col3 as col3_BB from ( select @rownum_AA:=@rownum_AA:=+1 as rownum, col1, col2, col3 from table_name where col2=1 ) as AA full outer join ( select @rownum_BB:=@rownum_BB:=+1 as rownum, col1, col2, col3 from table_name where col2=2 ) as BB using(rownum, col1) |
ここで、前記のイメージとは
col1 : 学年、col2 : クラス、col3 : 名前となります。
このコードでは、いったん1学年のみできるイメージなので、3学年行うには分割してUNIONします。
解説
細かい解説です。
1 2 3 |
select @rownum_AA:=@rownum_AA:=+1 as rownum, col1, col2, col3 from table_name where col2=1 |
これで、col2が1となっている行(1組)を抜き出して番号を付けます。同様に、
1 2 3 |
select @rownum_BB:=@rownum_BB:=+1 as rownum, col1, col2, col3 from table_name where col2=2 |
これでcol2が2となっている行 (2組) を抜き出して番号を付けます。
それらをfull outer join し、rownum, col1を条件にすることで、並べることができます。