如何在SQL中以通用方式转置表?

时间:2016-12-09 20:02:34

标签: mysql sql postgresql transpose

你如何转换这张表:

OLD_TABLE

+----+--------+-------------+-------------------+
| id | type   | field       | value             |
+----+--------+-------------+-------------------+
| 1  | person | gender      | female            |
+----+--------+-------------+-------------------+
| 1  | person | age         | 22                |
+----+--------+-------------+-------------------+
| 1  | person | name        | Julie Smith       |
+----+--------+-------------+-------------------+
| 1  | person | picture_url | www.pic.com/1.jpg |
+----+--------+-------------+-------------------+
| 2  | person | gender      | male              |
+----+--------+-------------+-------------------+
| 2  | person | name        | Johnny Parsons    |
+----+--------+-------------+-------------------+

进入这样一个表:

NEW_TABLE

+----+----------------+--------+------+-------------------+
| id | name           | gender | age  | picture_url       |
+----+----------------+--------+------+-------------------+
| 1  | Julie Smith    | female | 22   | www.pic.com/1.jpg |
+----+----------------+--------+------+-------------------+
| 2  | Johnny Parsons | male   | Null | Null              |
+----+----------------+--------+------+-------------------+

我们可以这样做一个查询:

INSERT INTO new_table SELECT
id::id as id,
max(case when field='name' then value else null end) as name,
max(case when field='gender' then value else null end) as gender,
max(case when field='age' then value else null end) as age,
max(case when field='picture_url' then value else null end) as picture_url
FROM old_table
WHERE 1=1
AND type = 'person'
GROUP BY
id
;

不幸的是,这个查询不具有推广性,如果我要添加新字段,那么这些字段将不会添加到新表中。有没有办法编写更通用的查询?

1 个答案:

答案 0 :(得分:1)

PIVOT(PostgreSQL中的CROSSTAB)可能就是您想要使用的内容。您有效地在查询中模拟PIVOT。但是,为此您需要知道您拥有的所有属性/列。

如果你不知道这些值,可以通过编程方式构造这样的SQL(在客户端,或者某些数据库允许执行生成的字符串)