【问题标题】:How to pivot without using PIVOT functions in SQL?如何在不使用 SQL 中的 PIVOT 函数的情况下进行透视?
【发布时间】: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   |

如果不使用任何数据透视函数,我将如何再次实现这一点?

【问题讨论】:

    标签: sql postgresql pivot


    【解决方案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 关键字,因此它不适合作为列名。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-06
        • 1970-01-01
        • 2013-01-11
        • 2020-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多