如何在PostgreSQL中实现类似pivot table的行转列功能转换车辆配置表
PostgreSQL行转列实现宽表转换方案
方案1:条件聚合(通用写法,无需扩展)
这是兼容性最高的实现方式,支持所有主流SQL数据库,无需启用额外扩展。此处使用MAX聚合仅用于提取非空值,替换为MIN也可得到相同结果:
SELECT c.id, c.name, MAX(CASE WHEN o.name = 'airbag' THEN o.value END) AS airbag, MAX(CASE WHEN o.name = 'sunroof' THEN o.value END) AS sunroof, MAX(CASE WHEN o.name = 'seat' THEN o.value END) AS seat FROM car c LEFT JOIN "option" o ON c.id = o.carid GROUP BY c.id, c.name ORDER BY c.id;
注意:option是PostgreSQL保留关键字,查询时需要用双引号包裹避免语法报错。
方案2:crosstab函数(PostgreSQL专属pivot实现)
如果配置项数量较多,可以用PostgreSQL内置的行转列函数实现,需要先启用tablefunc扩展:
-- 首次使用前先启用扩展 CREATE EXTENSION IF NOT EXISTS tablefunc; -- 执行pivot查询 SELECT * FROM crosstab( 'SELECT c.id, c.name, o.name, o.value FROM car c LEFT JOIN "option" o ON c.id = o.carid ORDER BY c.id, o.name', 'VALUES (''airbag''), (''sunroof''), (''seat'')' ) AS ct(id INT, name VARCHAR, airbag INT, sunroof INT, seat INT) ORDER BY id;
执行结果
两种方案最终返回的宽表结果一致:
| id | name | airbag | sunroof | seat |
|---|---|---|---|---|
| 1 | BMW | 1 | 1 | 4 |
| 2 | Volvo | 0 | 1 | 4 |
| 3 | Toyota | 0 | 0 | 5 |
内容的提问来源于stack exchange,提问作者amir hodaee
相关产品推荐
相关产品推荐

