縦持ちデータを横持ちデータに変換する方法(SQL)
前回はPythonのPandasで縦持ちデータを横持ちにする方法についてまとめましたが、今回はSQLです。PostgreSQLで実行した方法ですが、たぶんOracleやMySQLでも動くと思います。動かったなかったらごめんなさい。 縦持ちデータを横持ちデータに変換する方法についてはこちらにまとめています。
1.実施内容(概要)
SQLで以下のような縦持ちデータを
氏名 | 科目 | 点数 |
---|---|---|
A君 | 数学 | 100 |
A君 | 国語 | 70 |
A君 | 英語 | 60 |
A君 | ドイツ語 | 60 |
B君 | 数学 | 60 |
B君 | 国語 | 50 |
B君 | 英語 | 50 |
B君 | アラビア語 | 60 |
以下のような横持ちデータに変換します。
氏名 | 数学 | 国語 | 英語 | ドイツ語 | アラビア語 |
---|---|---|---|---|---|
A君 | 100 | 70 | 60 | 60 | NaN |
B君 | 60 | 50 | 50 | NaN | 60 |
2.SQL
select name, max(case subject when '数学' then score else null end) as math_score, max(case subject when '国語' then score else null end) as literature_score, max(case subject when '英語' then score else null end) as english_score, max(case subject when 'ドイツ語' then score else null end) as german_score, max(case subject when 'アラビア語' then score else null end) as arabic_score from t_score_verticle group by name;
3.解説
上記のmaxが一見謎ですが、これはgroup byを使用するために必要になります。縦持ちデータを横持ちデータに変換する際に、データをnameでgroup byするのですが、selectとgroup byは同じキーを指定しないと構文エラーになってしまうので、回避策としてmaxやsum等を指定することになります。
蛇足ですが、maxやsumを指定することでどのような挙動になるかは、以下の例を見ていただければ分かるかと思います。
例)A君・数学のデータが2行ある場合
氏名 | 科目 | 点数 |
---|---|---|
A君 | 数学 | 100 |
A君 | 数学 | 120 |
A君 | 国語 | 70 |
B君 | 数学 | 60 |
B君 | 国語 | 50 |
先に説明したSQLを実行すると、以下のような結果が返ってきます。
氏名 | 数学 | 国語 |
---|---|---|
A君 | 120 | 70 |
B君 | 60 | 50 |