【问题标题】:Postgres: convert single row to multiple rows (unpivot)Postgres:将单行转换为多行(unpivot)
【发布时间】:2018-04-15 01:57:35
【问题描述】:

我有一张桌子:

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  |
...

非常感谢任何有关类似示例链接的帮助。

【问题讨论】:

  • 只是select id,'a', a union select id,'b'b and so on?..
  • 谢谢!效果很好.. 它是否适合大量数据?
  • 没有什么比 ATM 更聪明的了 :)
  • 没关系。我在想有没有办法通过枢轴或非枢轴来做到这一点?因为我在这个表中有大量的数据,所以枢轴会更优化,而不是有多个联合,对吧?
  • 您必须查看tablefunc,尤其是crosstab 函数。

标签: sql database postgresql data-manipulation unpivot


【解决方案1】:

试一试:

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 是否是唯一的)

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

【讨论】:

    【解决方案2】:

    单个SELECTLATERAL 连接到VALUES 表达式可以完成这项工作:

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

    相关:

    【讨论】:

    • 如果我有一个包含多个值的 50 列这样的列表怎么办。有没有更好的办法?
    • @sanchitkhanna26:这适用于任意数量的列。我建议您从用例和目标的详细信息开始一个新问题。 (什么是“更好”?更快?更安全?更短?...)
    猜你喜欢
    • 2014-08-30
    • 2023-03-31
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    相关资源
    最近更新 更多