SQLで横ソートw
という事でサンプルをば。
WITH -- ターゲットのテーブル(サンプルデータ) CTE1 AS ( SELECT 1 KEY1, '牛肉' C1, '豚肉' C2, '鶏肉' C3 UNION ALL SELECT 2 KEY1, '羊肉' C1, null C2, '鹿肉' C3 ), -- 直積用の集合(GEN_ROW(rows)的な、再帰クエリで行生成するtable functionを準備しておくと何かと便利なのですが。。) CTE2 AS ( SELECT * FROM ( SELECT 1 SEQ1 UNION ALL SELECT 2 SEQ1 UNION ALL SELECT 3 SEQ1 ) T1 ), -- 横→縦展開 CTE3 AS ( SELECT KEY1, CASE SEQ1 WHEN 1 THEN C1 WHEN 2 THEN C2 WHEN 3 THEN C3 END C0 FROM CTE1, CTE2 ), -- 順位付け CTE4 AS ( SELECT ROW_NUMBER() OVER( PARTITION BY KEY1 ORDER BY C0 ) SEQ2, * FROM CTE3 ) -- 縦→横展開 SELECT KEY1, MAX(CASE WHEN SEQ2 = 1 THEN C0 END) C1, MAX(CASE WHEN SEQ2 = 2 THEN C0 END) C2, MAX(CASE WHEN SEQ2 = 3 THEN C0 END) C3 FROM CTE4 GROUP BY KEY1 ;
結果です。
KEY1 C1 C2 C3 ----------- ---- ---- ---- 1 牛肉 鶏肉 豚肉 2 NULL 鹿肉 羊肉
SQL Serverで恐縮ですが、似たような事は他のRDBMSでもできます。
以下オマケ
中間イメージです。
--CTE1 KEY1 C1 C2 C3 ----------- ---- ---- ---- 1 牛肉 豚肉 鶏肉 2 羊肉 NULL 鹿肉 --CTE2 SEQ1 ----------- 1 2 3 --CTE3 KEY1 C0 ----------- ---- 1 牛肉 1 豚肉 1 鶏肉 2 羊肉 2 NULL 2 鹿肉 --CTE4 SEQ2 KEY1 C0 -------------------- ----------- ---- 1 1 牛肉 2 1 鶏肉 3 1 豚肉 1 2 NULL 2 2 鹿肉 3 2 羊肉
余談ですが、
SELECT * FROM ( SELECT * FROM ( SELECT * FROM ( SELECT * FROM T1 ) T2 ) T3 ) T4 ;
みたいな入れ子よりも、近年では、共通表式(Common Table Expression)を使ってブロック化する事がオススメです。