需要从 SQL 表中透视数据

Posted

技术标签:

【中文标题】需要从 SQL 表中透视数据【英文标题】:Need to PIVOT data from table in SQL 【发布时间】:2021-01-07 09:56:29 【问题描述】:

我有一个名为 BasketTable 的 sql 表,其中包含类似的数据

Assists  Rebounds   Steals  Blocks  Fouls   TeamId
10        32          8       6      11       13
18        36          8       6      9         9

我想要这样的输出

StatsName    Team1   Team2
 Assists      10      18
 Rebounds     32      36
 Steals        8       8
 Blocks        6       6
 Fouls        11       9

如果示例中有 3 行,则在输出中添加第三个团队数据列

我正在为此尝试此查询

select StatsName, HomeTeam from 
(
select Assists, DefensiveRebounds as Rebounds, Steals, Blocks, PersonalFouls as Fouls
from CombinationStatistics cs
where GameId = 1082960
) x
 unpivot (
    HomeTeam for StatsName IN (Assists, Rebounds, Steals, Blocks, Fouls)
 ) p

上面的查询给我这个输出,

StatsName   HomeTeam
Assists       10
Rebounds      32
Steals         8
Blocks         6
Fouls         11
Assists       18
Rebounds      36
Steals         8
Blocks         6
Fouls          9

我知道那是错误的,我想要第二个团队的另一个专栏,现在它在一个专栏中。如何通过 TeamId 区分数据?

【问题讨论】:

那么...您的问题/问题是什么?你读过docs.microsoft.com/en-us/sql/t-sql/queries/…了吗? 您将需要在此处进行 unpivot 和 pivot 操作。如果您的团队数量不定,那将是一些真正“混乱”的动态 SQL。我强烈建议您不要在不熟悉 SQL 的情况下这样做。似乎是您的表示层要做的事情;例如 s-s-rS 中的矩阵或 Microsoft Excel 中的数据透视表。 您需要添加TeamID。就是这样! 我添加了 TeamID,但它不起作用@MaciejLos 这不是“全部”@MaciejLos。然后,OP 将需要转置他们未转置的数据,即便如此,它也只能处理 2 个团队,超过 2 个。 【参考方案1】:

这适用于特定数量的团队,在本例中为 2。但是,如果您有更多团队,它不会返回更多列。那是因为做到这一点的唯一方法是使用动态 SQL,老实说,取消透视,然后动态旋转是混乱的,而不是你应该在 SQL 中做的事情。这是表示层的工作。

WITH RNs AS(
    SELECT Assists,
           Rebounds,
           Steals,
           Blocks,
           Fouls,
           TeamId,
           ROW_NUMBER() OVER (ORDER BY TeamID DESC) AS RN
   FROM dbo.YourTable),
Unpvt AS(
    SELECT RN.RN,
           V.StatName,
           V.StatNumber
    FROM RNs RN
         CROSS APPLY (VALUES('Assists',RN.Assists),
                            ('Rebounds',RN.Rebounds),
                            ('Steals',RN.Steals),
                            ('Fouls',RN.Fouls))V(StatName,StatNumber))
SELECT U.StatName,
       MAX(CASE U.RN WHEN 1 THEN StatNumber END) AS Team1,
       MAX(CASE U.RN WHEN 2 THEN StatNumber END) AS Team2
FROM Unpvt U;
           

当然,如果您不了解上述内容,则不应该采用动态方法,因为您没有希望支持它;需要支持的是你,而不是 Stack Overflow 上的社区。​​p>

【讨论】:

【参考方案2】:

正如@Larnu 提到的,您需要取消透视数据并再次透视它们。见:

SELECT StatsName, [9], [13]
FROM
(
  SELECT TeamId, StatsName, HomeTeam
  FROM
  (
    SELECT 10 Assists, 32 Rebounds, 8  Steals, 6 Blocks, 11 Fouls, 13  TeamId
    UNION ALL
    SELECT 18 Assists, 36 Rebounds, 8  Steals, 6 Blocks, 9 Fouls, 9  TeamId
  ) pvt
  unpivot
  (
    HomeTeam for StatsName IN (Assists, Rebounds, Steals, Blocks, Fouls)
  ) unpvt
) src
pivot(SUM(HomeTeam) for TeamId IN([9], [13])) final

db_fiddle

【讨论】:

以上是关于需要从 SQL 表中透视数据的主要内容,如果未能解决你的问题,请参考以下文章

使用 Sql Developer Oracle 的动态数据透视查询

用于从 VIEW 表中提取数据的 SQL 透视查询

从 SQL Server DB 更新单独工作表中的数据后自动刷新 Excel 2007 数据透视表

MS SQL Server 中的动态数据透视

动态 SQL 使用多列交叉应用来反透视数据

在 sql 中创建一个带联接的数据透视表