【问题标题】:Transpose columns into row in MS SQL Server - dynamic UNPIVOT在 MS SQL Server 中将列转置为行 - 动态 UNPIVOT
【发布时间】:2021-12-16 07:59:42
【问题描述】:

我有一个如下所示的 MS SQL Server 表:

Example SQL table structure

我在每一行都有员工,一些描述他们的列,然后是我有 QuotaAchievement 的财务季度列。

如您所料,将添加新的财政季度,每个季度的员工都不相同。

对我来说,要使用 Tableau 中的数据,这将是所需的格式:

Desired format

我想将员工保留为单独的行,将其描述性列保留为列,但将配额和成就汇总到一列中,并为每个单独的季度单独行。

如果一个简单的解决方案需要,我可以有一个可能的财政季度列表,稍后将显示为列。

我一直在阅读有关动态枢轴的内容,因为我想这将是我的解决方案,但由于我对 UNPIVOT 函数非常陌生,因此未能实现这种格式。

任何指导将不胜感激

【问题讨论】:

  • 不鼓励使用图像的原因有很多 - 最好将该信息包含在包含 DDL 和示例数据的脚本中。您的表已经旋转。您需要执行与枢轴相反的操作 - 取消枢轴以将列转换为行(每行一个 emp/四分之一)。也许现在是重新考虑这种模式选择的好时机。
  • 我不是数据库所有者,只是数据的用户,很遗憾,重新考虑原始设置不是我的优点
  • 你有哪个版本的 SQL Server?
  • @Charlieface,我们有一个 MS SQL Server
  • SQL Server 的哪个版本,运行select @@version

标签: sql sql-server transpose unpivot dynamic-pivot


【解决方案1】:

我已经恢复到一个简单的解决方案,而不是动态的解决方案,这需要我每年进行一次维护,但它仍然是一个快速的解决方案。

我已经单独查询了​​每个季度的数据,并使用 CASE 语句创建了一个名为“财政季度”的新字段,并且我手动输入了财政季度值。我已将各自的列重命名为配额和成就,忽略其名称中的财政季度参考。

使用 UNION ALL 组合查询,我的查询很长,但表结构正确。

感谢所有参与调查的人

【讨论】:

  • 您介意分享您的代码的相关部分吗?您的解释很有用,但您的 SQL 语句的基本结构对未来遇到类似问题的读者最有用。
【解决方案2】:

这是一个高度非规范化的结构,但如果这是你必须使用的......

您可以先使用FOR JSON 聚合所有列,然后使用OPENJSON 选择要返回到单独行中的列,从而取消透视所有列

SELECT
  t.EmployeeID,
  upv.*
FROM YourTable t
CROSS APPLY (
    SELECT t.*
    FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) j(json)
CROSS APPLY (
    SELECT
      [Fiscal Quarter] = LEFT(j2.[key], 7),
      Quota = SUM(CASE WHEN j2.[key] LIKE '%Quota' THEN CAST(j2.value AS int) END),
      Achievement = SUM(CASE WHEN j2.[key] LIKE '%Achievement' THEN CAST(j2.value AS int) END)
    FROM OPENJSON(j.json) j2
        -- [key] is the column name
    WHERE j2.[key] LIKE '%Quota' OR j2.[key] LIKE '%Achievement'
    GROUP BY
      LEFT(j2.[key], 7)
) upv

您可以在旧版本的 SQL Server 上使用 FOR XML 实现类似的想法

【讨论】:

  • 抱歉,我忘了提到我们使用 MS SQL 服务器,所以我认为这不适合我:(
  • 这适用于 2016 年以后的任何版本
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-24
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 2013-12-05
相关资源
最近更新 更多