【问题标题】:Transform data from rows to columns using SQL使用 SQL 将数据从行转换为列
【发布时间】:2020-10-15 10:02:22
【问题描述】:

数据结构说明

假设我们有一个订单项目表(即一行代表一个订单项目)。每个订单项都有product_type(“A”或“B”)、amountcurrency。 一份订单 (order_id) 可以包含 1..4 个订单项目。在一个订单中,可以有一种货币(这样的订单由 1..2 个订单项目组成)或两种货币(这样的订单由 2..4 个订单项目组成)。

我需要将其转换为订单表(即一行代表一个订单)。我是SQL window functions 的新手,所以任何提示都将不胜感激。

示例

原始数据结构:

| order_id |产品类型 |金额 |货币 | | 1 |一个 | 2 |美元 | | 1 |一个 | 1 |欧元 | | 1 |乙| 6 |美元 | | 1 |乙| 5 |欧元 | | 2 |一个 | 7 |美元 | | 2 |乙| 5 |美元 | | 2 |乙| 3 |加元 | | 3 |一个 | 2 |美元 | | 3 |乙| 4 |澳元 | | 4 |一个 | 1 |新西兰元 | | 4 |乙| 2 |新西兰元 | | 5 |一个 | 8 |欧元 |

目标数据结构:

| order_id | a_amount1 | a_cur1 | a_amount2 | a_cur2 | b_amount1 | b_cur1 | b_amount2 | b_cur2 | | 1 | 2 |美元 | 1 |欧元 | 6 |美元 | 5 |欧元 | | 2 | 7 |美元 | | | 5 |美元 | 3 |加元 | | 3 | 2 |美元 | | | 4 |澳元 | | | | 4 | 1 |新西兰元 | | | 2 |新西兰元 | | | | 5 | 8 |欧元 | | | | | | |

【问题讨论】:

    标签: sql pivot window-functions


    【解决方案1】:

    我们可以尝试借助ROW_NUMBER 进行数据透视查询来生成用于区分货币的系列:

    WITH cte AS (
        SELECT *, ROW_NUMBER() OVER (PARTITION BY order_id, product_type ORDER BY currency) rn
        FROM yourTable
    )
    
    SELECT
        order_id,
        MAX(CASE WHEN product_type = 'A' AND rn = 1 THEN amount END)   AS a_amount1,
        MAX(CASE WHEN product_type = 'A' AND rn = 1 THEN currency END) AS a_cur1,
        MAX(CASE WHEN product_type = 'A' AND rn = 2 THEN amount END)   AS a_amount2,
        MAX(CASE WHEN product_type = 'A' AND rn = 2 THEN currency END) AS a_cur2,
        MAX(CASE WHEN product_type = 'B' AND rn = 1 THEN amount END)   AS b_amount1,
        MAX(CASE WHEN product_type = 'B' AND rn = 1 THEN currency END) AS b_cur1,
        MAX(CASE WHEN product_type = 'B' AND rn = 2 THEN amount END)   AS b_amount2,
        MAX(CASE WHEN product_type = 'B' AND rn = 2 THEN currency END) AS b_cur2
    FROM cte
    GROUP BY
        order_id
    ORDER BY
        order_id;
    

    Demo

    【讨论】:

    • 只有一件小事:对于 product_type = 'B' 的情况,应该有 b_* 列别名。但逻辑工作正常,将使用更大的数据集进行进一步测试。谢谢蒂姆的精彩课程!
    猜你喜欢
    • 2014-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-24
    • 1970-01-01
    相关资源
    最近更新 更多