【问题标题】:SQL Server - Pivot Convert rows to columns (with additional row data)SQL Server - Pivot 将行转换为列(带有额外的行数据)
【发布时间】:2020-06-13 22:40:02
【问题描述】:

有人可以帮我处理这个 SQL 吗?

我希望通过 id、类型、颜色、日期将多行转换为列

挑战:我有多个列要保留/显示在透视表上。

id | type   | color  | date      | country_code | cost
---+--------+--------+-----------+--------------+-------
1  | report | red    | 2020-09-01| US           | 1
1  | report | red    | 2020-09-01| EU           | 2
1  | report | red    | 2020-09-01| RU           | 3
1  | report | red    | 2020-09-01| AP           | 4
1  | report | blue   | 2020-09-02| US           | 5   
1  | report | blue   | 2020-09-02| EU           | 6
1  | report | blue   | 2020-09-02| RU           | 7
1  | report | blue   | 2020-09-02| AP           | 8
2  | report | green  | 2020-09-02| US           | 9
2  | report | green  | 2020-09-02| EU           | 10
2  | report | green  | 2020-09-02| RU           | 11
2  | report | green  | 2020-09-02| AP           | 12
2  | report | blue   | 2020-09-03| US           | 13
2  | report | blue   | 2020-09-03| EU           | 14
2  | report | blue   | 2020-09-03| RU           | 15
2  | report | blue   | 2020-09-03| AP           | 16

期望的输出:

id | type   | color | date       | US | EU | RU | AP
---+--------+-------+------------+----+----+----+----
1  | report | red   | 2020-09-01 | 1  | 2  | 3  | 4
1  | report | blue  | 2020-09-02 | 5  | 6  | 7  | 8
2  | report | green | 2020-09-02 | 9  | 10 | 11 | 12
2  | report | blue  | 2020-09-03 | 13 | 14 | 15 | 16

已知信息:

  • 只有 4 个国家代码。
  • color 的值将与以下各项相同:id、类型、日期。

不确定编写此 SQL 的最简洁/最佳方式是什么。

我尝试过使用

ROW_NUMBER() OVER(PARTITION BY xxx ORDER BY yyy)

PIVOT,但无法获得我想要的结果

【问题讨论】:

    标签: sql sql-server pivot unpivot partition-by


    【解决方案1】:

    我认为条件聚合可以满足您的需求:

    select id, type, color, date,
           max(case when country_code = 'US' then cost end) as us,
           max(case when country_code = 'EU' then cost end) as eu,
           max(case when country_code = 'RU' then cost end) as ru,
           max(case when country_code = 'AP' then cost end) as AP
    from t
    group by id, type, color, date;
    

    【讨论】:

    • 抱歉,我不小心把美国值粘贴了两次。我纠正了它。所以 country_code 应该是 'US, EU, RU, AP'。
    • 我玩了一圈,觉得我得到了这个:``` SELECT id, type, color, date, [US], [EU], [RU], [AP] FROM ( SELECT id,类型、颜色、日期、国家代码、成本 FROM tableX ) t PIVOT ( MAX(cost) FOR country_code IN ( [US], [EU], [RU], [AP] ) ) p ```
    • @JackyLam 。 . .那么条件聚合就更简单了。
    • 啊,是的!愚蠢的我,当它非常简单时尝试非常复杂的查询。非常感谢戈登!!厚颜无耻的问题:在一个非常大的数据集(超过数百万)中,您是否碰巧知道使用group bypivot 的性能是否更好? (假设我已正确索引列)
    • 我的理解是pivot 在任何实现它的数据库中都没有提供性能优势。也就是说,优化器会随着时间而变化,因此始终值得测试。
    【解决方案2】:

    我玩了一圈,觉得我明白了:

    SELECT id, type, color, date, [US], [EU], [RU], [AP]
    FROM
    (
      SELECT id, type, color, date, country_code, cost FROM tableX
    ) t
    PIVOT
    (
      MAX(cost)
      FOR country_code IN ( [US], [EU], [RU], [AP] )
    ) p
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多