Postgres中如何将指定商品的价格列值转为行?求PIVOT替代方案
Postgres实现指定Item的列转行输出(替代PIVOT方案)
问题背景
现有一张名为price的表,结构及数据如下:
-- 表结构 CREATE TABLE price ( Item VARCHAR(10), Price_01 INT, Price_02 INT, Price_03 INT, Price_04 INT ); -- 测试数据 INSERT INTO price VALUES ('Bat', 1000, 1100, 1200, 1300), ('Ball', 11000, 1200, 1300, 1400);
需求:根据输入的Item值,将对应行的Price_01至Price_04列数据转为单行输出(例如输入Bat时,输出四个价格值各占一行)。
解决方案(Postgres无内置PIVOT/UNPIVOT,以下为替代方案)
方案1:使用UNNEST+数组(最简洁)
将目标Price列打包成数组,再通过UNNEST函数将数组元素展开为单独行:
SELECT UNNEST(ARRAY[Price_01, Price_02, Price_03, Price_04]) AS price_value FROM price WHERE Item = 'Bat';
输出结果:
price_value ------------ 1000 1100 1200 1300
方案2:使用UNION ALL(灵活处理单列逻辑)
如果需要对每个Price列单独添加转换或过滤逻辑,可使用UNION ALL逐个列查询:
SELECT Price_01 AS price_value FROM price WHERE Item = 'Bat' UNION ALL SELECT Price_02 AS price_value FROM price WHERE Item = 'Bat' UNION ALL SELECT Price_03 AS price_value FROM price WHERE Item = 'Bat' UNION ALL SELECT Price_04 AS price_value FROM price WHERE Item = 'Bat';
注意:
UNION ALL会保留所有行(包括重复值),效率比UNION更高,适合不需要去重的场景。
方案3:使用LATERAL JOIN+VALUES(可读性强,易扩展)
通过LATERAL JOIN关联包含Price列的VALUES子句,实现列转行:
SELECT p.price_value FROM price JOIN LATERAL ( VALUES (Price_01), (Price_02), (Price_03), (Price_04) ) AS p(price_value) ON true WHERE Item = 'Bat';
这种方式新增Price列时,只需在VALUES中添加对应行即可,维护成本低。
内容的提问来源于stack exchange,提问作者user1463065
相关产品推荐
相关产品推荐

