如何在不使用 SQL 中的 PIVOT 函数的情况下进行透视?
Posted
技术标签:
【中文标题】如何在不使用 SQL 中的 PIVOT 函数的情况下进行透视?【英文标题】:How to pivot without using PIVOT functions in SQL? 【发布时间】:2021-05-15 17:26:42 【问题描述】:我想在不使用任何 PIVOT
函数但仅使用纯 SQL 的情况下对表进行透视(例如 PostgreSQL 语法)。
以这个数据集为例:
Order | Element | Value |
---------------------------
1 | Item | Bread |
1 | Quantity | 3 |
1 | TotalCost | 3,30 |
2 | Item | Pizza |
2 | Quantity | 2 |
2 | TotalCost | 10 |
3 | Item | Pasta |
3 | Quantity | 5 |
3 | TotalCost | 2,50 |
我希望以Order
列为中心,并有类似的内容:
Order | Item | Quantity | TotalCost |
-------------------------------------
1 | Bread | 3 | 3,30 |
2 | Pizza | 2 | 10 |
3 | Pasta | 5 | 2,50 |
如果不使用任何数据透视函数,我将如何再次实现这一点?
【问题讨论】:
【参考方案1】:解决方案 A
使用CASE WHEN
语句:
SELECT Order,
MAX(CASE WHEN Element = 'Item' THEN Value END) AS Item,
MAX(CASE WHEN Element = 'Quantity' THEN Value END) AS Quantity,
MAX(CASE WHEN Element = 'TotalCost' THEN Value END) AS TotalCost
FROM MyTable
GROUP BY 1
解决方案 B
使用自左连接:
SELECT A.Order, A.Item, B.Quantity, C.TotalCost
FROM
(SELECT Order, Value as Item
FROM MyTable
WHERE Element = 'Item') as A
LEFT JOIN
(SELECT Order, Value as Quantity
FROM MyTable
WHERE Element = 'Quantity') as B ON A.Order = B.Order
LEFT JOIN
(SELECT Order, Value as TotalCost
FROM MyTable
WHERE Element = 'TotalCost') as C ON B.Order = C.Order
后者可能没有那么高效,但有些用例可能会派上用场。
【讨论】:
【参考方案2】:在 Postgres 中,您将使用 FILTER
:
SELECT Order,
MAX(Value) FILTER (WHERE Element = 'Item') AS Item,
MAX(Value) FILTER (WHERE Element = 'Quantity') AS Quantity,
MAX(Value) FILTER (WHERE Element = 'TotalCost') AS TotalCost
FROM MyTable
GROUP BY 1;
请注意,ORDER
是一个 SQL 关键字,因此它不适合作为列名。
【讨论】:
以上是关于如何在不使用 SQL 中的 PIVOT 函数的情况下进行透视?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用数据透视和反透视的情况下在 SQL Server 中水平显示数据?
如何在不使用 Group By / 有函数的情况下过滤 SQL 中的数据
如何在不使用临时表或视图的情况下在多个列上使用 PIVOT [重复]