PostgreSQL 中的反透视表
Posted
技术标签:
【中文标题】PostgreSQL 中的反透视表【英文标题】:Unpivot table in PostgreSQL 【发布时间】:2020-10-08 17:48:16 【问题描述】:作为 SUM(Case....End) 的结果,我有下表。
Account Product_A Product_B Product_C
101 1000 2000 3000
102 2000 1000 0
103 2000 1000 0
104 2000 1000 2000
我想把它放回原来的桌子。像这样:
Account Product Qty
101 A 1000
... .. ....
我认为“Unpivot”可以在 MS SQL Server 中完成。但我只使用 PostgreSQL。 Postgresql 中可以返回/取消组合上表的 Unpivot 的等价物是什么? 谢谢
【问题讨论】:
【参考方案1】:您可以使用带值子句的横向连接:
select t.account, u.product, u.qty
from the_table t
cross join lateral (
values ('A',product_a), ('B', product_b), ('C', product_c)
) as u(product, qty)
order by t.account;
Online example
【讨论】:
【参考方案2】:我认为unnest
会帮助你:
SELECT Account,
unnest(array['A', 'B', 'C']) AS Product,
unnest(array[Product_A, Product_B, Product_C]) AS Qty
FROM test
ORDER BY Account;
FIDDLE
【讨论】:
【参考方案3】:即使通过使用 JSON 函数将更多列(例如 Product_D
)添加到表中,您也可以动态地取消透视这些列:
SELECT account, UPPER(SPLIT_PART((js).key, '_', 2)) AS Product, (js).value AS Qty
FROM( SELECT rj->>'account' AS Account, JSON_EACH_TEXT(rj) AS js
FROM ( SELECT ROW_TO_JSON(t) AS rj FROM t) AS q1 ) AS q2
WHERE (js).key != 'account';
Demo
同时根据为现有列名 (Product_A/B/C
) 定义的模式拆分 Products 的列名,而无需明确指定每个字母。
【讨论】:
以上是关于PostgreSQL 中的反透视表的主要内容,如果未能解决你的问题,请参考以下文章