Postgres:将单行转换为多行(反旋)

8

我有一个表格:

Table_Name: price_list
---------------------------------------------------
| id | price_type_a | price_type_b | price_type_c |
---------------------------------------------------
| 1  |    1234      |     5678     |     9012     |
| 2  |    3456      |     7890     |     1234     |
| 3  |    5678      |     9012     |     3456     |
---------------------------------------------------

我需要在Postgres中编写一个查询语句,使其返回以下结果:
---------------------------
| id | price_type | price |
---------------------------
| 1  |  type_a    | 1234  |
| 1  |  type_b    | 5678  |
| 1  |  type_c    | 9012  |
| 2  |  type_a    | 3456  |
| 2  |  type_b    | 7890  |
| 2  |  type_c    | 1234  |
...

如有类似的示例链接,敬请提供帮助。


仅选择 id,'a',a 并联合选择 id,'b',b 等等。 - Vao Tsun
谢谢!这很好用。。。对于大量数据,它会是最优的选择吗? - skybunk
目前为止,没有比这更聪明的东西了 :) - Vao Tsun
没问题。我在想是否有一种通过透视表或非透视表的方式来实现呢?因为这个表格里有大量的数据,使用透视表会比多次联接更加优化,对吧? - skybunk
@ErwinBrandstetter和OP:抱歉,我完全搞错了。 - s.m.
显示剩余3条评论
2个回答

13

使用带有 LATERAL 连接到 VALUES 表达式的单个 SELECT 可以完成将列“解构”为单独行的工作:

SELECT p.id, v.*
FROM   price_list p
CROSS  JOIN LATERAL (
   VALUES
      ('type_a', p.price_type_a)
    , ('type_b', p.price_type_b)
    , ('type_c', p.price_type_c)
   ) v (price_type, price);

相关:


1
如果我有一个像这样带有多个值的50列列表,有更好的方法吗? - sanchitkhanna26
@sanchitkhanna26:这适用于任意数量的列。我建议您开始一个新问题,并提供您使用情况和目标的详细信息。(什么更好?更快?更安全?更短?...) - Erwin Brandstetter

0

尝试类似这样的东西:

select id, 'type_a',type_a  from price_list
union all
select id, 'type_b',type_b  from price_list
union all
select id, 'type_c',type_c  from price_list
;

更新 正如a_horse_with_no_name所建议的那样,联合是选择DISTINCT值的方法,对于这里来说,UNION ALL更受欢迎 - 以防万一(我不知道id是否唯一)

当然,如果是英国 - 就没有区别了


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接