2017-01-05 6 views
1

私は行全体を返すクエリがあり、この結果を新しいテーブルにピボットする必要があります。PostgreSQLのピボット列

SELECT id_no, stud_name, group_no, class_1, class_2, class_3, class_4 FROM tbl_stud_class 

これには次の値を返します。

| id_no | stud_name | group_no | class_1 | class_2 | class_3 | class 4 | 
| 1  | John Doe | A11  | 84  | 60  | 80  | 79  | 

私は、この行を返すことができるようにする必要があります。

| id_no | stud_name | group_no | class | grade | 
| 1  | John Doe | A11  | class_1 | 84 | 
| 1  | John Doe | A11  | class_2 | 60 | 
| 1  | John Doe | A11  | class_3 | 80 | 
| 1  | John Doe | A11  | class_4 | 79 | 

誰かがこれをしてください行う方法に私を指すことができますか? 私はPostgreSQLについてとても新しいので、どこからどのように起動するのか分かりません。

ありがとうございました!

答えて

1

あなたは、あまりにもうまく動作のPostgreSQL 9.3+

SELECT id_no, stud_name, group_no, class, grade 
FROM tbl_stud_class 
     CROSS JOIN LATERAL (VALUES 
        ('class_1', class_1), 
        ('class_2', class_2), 
        ('class_3', class_3), 
        ('class_4', class_4) 
      ) l(class, grade) 
+0

短く簡潔に!大好きです!本当にありがとう!!! – Smiley

0

はこのニーズ:

WITH tbl_stud_class 
    (id_no, stud_name, group_no, class_1, class_2, class_3, class_4) AS 
(
    VALUES 
     (1, 'John Doe', 'All', 84, 60, 80, 79), 
     (2, 'Aberel Dalton', 'Some', 75, 32, NULL, 80) 
) 

SELECT 
    id_no, stud_name, group_no, 'class_1' AS class, class_1 AS grade 
FROM 
    tbl_stud_class 
WHERE 
    class_1 IS NOT NULL 
UNION 
SELECT 
    id_no, stud_name, group_no, 'class_2' AS class, class_2 AS grade 
FROM 
    tbl_stud_class 
WHERE 
    class_2 IS NOT NULL 
UNION 
SELECT 
    id_no, stud_name, group_no, 'class_3' AS class, class_3 AS grade 
FROM 
    tbl_stud_class 
WHERE 
    class_3 IS NOT NULL 
UNION 
SELECT 
    id_no, stud_name, group_no, 'class_4' AS class, class_4 AS grade 
FROM 
    tbl_stud_class 
WHERE 
    class_4 IS NOT NULL 
ORDER BY 
    id_no, class ; 

私の知る限りを、自動的な方法でこれを行う方法はありません。 PostgreSQLにはcrosstabという関数がありますが、これはPIVOTを実行しますが、それは(あなたの望む出力からあなたの入力に)逆の働きをします。


あなたはarraysunnestを使用して、短い代替手段を持っている:

WITH tbl_stud_class 
    (id_no, stud_name, group_no, class_1, class_2, class_3, class_4) AS 
(
    VALUES 
     (1, 'John Doe', 'All', 84, 60, 80, 79), 
     (2, 'Aberel Dalton', 'Some', 75, 32, NULL, 80) 
) 

SELECT 
    * 
FROM 
(
    SELECT 
     id_no, stud_name, group_no, 
     unnest(ARRAY['class_1', 'class_2', 'class_3', 'class_4']) AS class, 
     unnest(ARRAY[ class_1, class_2, class_3, class_4 ]) AS grade 
    FROM 
     tbl_stud_class 
) AS s0   
WHERE 
    grade is not null 
ORDER BY 
    id_no, class ; 
+0

LATERALを使用することができます!本当にありがとう! – Smiley