我有一个返回整行的查询,我需要将此结果转换为新表。
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很新,所以我不知道在哪里以及如何开始。
谢谢!
答案 0 :(得分:2)
您也可以在postgresql 9.3 +
中使用LATERALSELECT 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)
答案 1 :(得分: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 ;
AFAIK,无法以自动方式执行此操作。 PostgreSQL有crosstab
函数,它可以执行PIVOT,但它可以反过来(从您想要的输出到输入)。
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 ;