【问题标题】:Is there a way to create a "pivot group" of columns with t-sql?有没有办法用 t-sql 创建列的“枢轴组”?
【发布时间】:2019-12-18 15:13:44
【问题描述】:

这似乎是一种常见的需求,但不幸的是,我找不到解决方案。

假设您有一个输出以下内容的查询:

| TimeFrame  | User       | Metric1 | Metric2 |
+------------+------------+---------+---------+
| TODAY      | John Doe   | 10      | 20      |
| MONTHTODAY | John Doe   | 100     | 200     |
| TODAY      | Jack Frost | 15      | 25      |
| MONTHTODAY | Jack Frost | 150     | 250     |

数据透视后我需要的输出是如下所示的数据:

| User       | TODAY_Metric1 | TODAY_Metric2 | MONTHTODAY_Metric1 | MONTHTODAY_Metric2 |
+------------+---------------+---------------+--------------------+--------------------+
| John Doe   | 10            | 20            |100                 | 200                |
| Jack Frost | 15            | 25            |150                 | 250                |

请注意,我正在对 TimeFrame 进行旋转,但是,Metric1Metric2 列仍然是列,但按时间范围值分组。

这可以在标准PIVOT 语法中完成,还是我需要编写一个更复杂的查询来将这些数据集中到一个特定于我需要的结果集中?

【问题讨论】:

  • 这能回答你的问题吗? how to make your data horizontal
  • 这是一场斗争的原因是因为您违反了重复组(Metric1,Metric2)的 1NF。如果这被规范化,这将是无痛的。但是下面的条件聚合是处理这个问题的最好方法。

标签: sql sql-server tsql group-by pivot


【解决方案1】:

您可以使用条件聚合来做到这一点:

select
    user,
    sum(case when timeframe = 'TODAY' then Metric_1 end) TODAY_Metric1,
    sum(case when timeframe = 'TODAY' then Metric_2 end) TODAY_Metric2,
    sum(case when timeframe = 'MONTHTODAY' then Metric_1 end) MONTHTODAY_Metric1,
    sum(case when timeframe = 'MONTHTODAY' then Metric_2 end) MONTHTODAY_Metric2
from mytable
group by user

我更喜欢条件聚合技术而不是特定于供应商的实现,因为:

  • 我发现它更易于理解和维护
  • 它是跨 RDBMS(因此如果需要,您可以轻松地将其移植到其他数据库)
  • 它的性能通常与供应商实施一样好,甚至比供应商实施(通常在后台依赖它)更好

【讨论】:

  • 呃,今天我的头没拧好。这就是答案。当我的工作将我分散到许多不同类型的职责时,就会发生这种情况(我忘记了)。谢谢提醒。
猜你喜欢
  • 2012-09-23
  • 2011-02-24
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多