sql-server - SQL Server 在不聚合的情况下透视数据

标签 sql-server t-sql dynamic pivot

我知道这个问题之前已经被问过很多很多次了,但我很难找到我需要的解决方案。

数据:

Id   FKId   TypeId   Score   ScoreDate
1    317    1        90      2019-01-01
2    317    1        80      2019-01-02
3    317    2        65      2019-01-03
4    317    2        80      2019-01-04
5    318    1        82      2019-01-01
6    318    1        78      2019-01-02
7    318    2        55      2019-01-03
8    318    2        63      2019-01-04

预期结果:

FkId   A1   A2   B1  B2
317    90   80   65  80
318    82   78   55  63

我尝试使用数据透视表来获取数据,但我偶然发现你需要使用聚合函数,这会导致错误的结果。其中一项尝试的示例:

select *
from 
(
  select [FkId], [TypeId], [Score]
  from #yt
) src
pivot
(
  max([Score])
  for [TypeId] in ([1], [2], [3])
) piv;

query result:
FkId  1     2       3
101   83    82  NULL
102   96    80  NULL

我知道我需要多个查询才能获得预期结果,但这不是我关心的,现在我只想将一种类型的分数与每个分数转置到它自己的列中。

任何帮助都可以。

最佳答案

试试这个:

CREATE TABLE #yt
(
    [Id] INT
   ,[FKId] INT
   ,[TypeId] TINYINT
   ,[Score] INT
   ,[ScoreDate] DATE
)

INSERT INTO #yt
VALUES (1, 317, 1, 90, '2019-01-01')
      ,(2, 317, 1, 80, '2019-01-02')
      ,(3, 317, 2, 65, '2019-01-03')
      ,(4, 317, 2, 80, '2019-01-04')
      ,(5, 318, 1, 82, '2019-01-01')
      ,(6, 318, 1, 78, '2019-01-02')
      ,(7, 318, 2, 55, '2019-01-03')
      ,(8, 318, 2, 63, '2019-01-04');

select *
from 
(
    SELECT [FKId]
        ,CHAR(64 + DENSE_RANK() OVER (PARTITION BY FKID ORDER BY TypeID)) + CAST(DENSE_RANK() OVER (PARTITION BY FKID, TypeID ORDER BY [ScoreDate]) AS VARCHAR(12))
        ,[Score]
    FROM #yt
) src ([FKId], [TypeID], [Score])
pivot
(
  max([Score])
  for [TypeId] in ([A1], [A2], [B1], [B2])
) piv;


DROP TABLE #yt;

或者如果你想让它变得动态:

DECLARE @DynamicTSQLStatement NVARCHAR(MAX)
       ,@DynamicColumns NVARCHAR(MAX)

SET @DynamicColumns = STUFF
                        (
                            (
                                SELECT DISTINCT ',[' + CHAR(64 + DENSE_RANK() OVER (PARTITION BY FKID ORDER BY TypeID)) + CAST(DENSE_RANK() OVER (PARTITION BY FKID, TypeID ORDER BY [ScoreDate]) AS VARCHAR(12)) + ']'
                                FROM #yt                               
                                FOR XML PATH('') ,TYPE
                            ).value('.', 'NVARCHAR(MAX)')
                            ,1
                            ,1
                            ,''
                        );

SET @DynamicTSQLStatement = N'
select *
from 
(
    SELECT [FKId]
        ,CHAR(64 + DENSE_RANK() OVER (PARTITION BY FKID ORDER BY TypeID)) + CAST(DENSE_RANK() OVER (PARTITION BY FKID, TypeID ORDER BY [ScoreDate]) AS VARCHAR(12))
        ,[Score]
    FROM #yt
) src ([FKId], [TypeID], [Score])
pivot
(
  max([Score])
  for [TypeId] in ('+@DynamicColumns+')
) piv;'


EXEC sp_executesql @DynamicTSQLStatement;

关于sql-server - SQL Server 在不聚合的情况下透视数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54609860/

相关文章:

sql-server - 在 T-SQL 中指定给定日期的正确方法

python - django-mutant 在 django-admin 中创建模型

c++ - 如何在不使用 objective-c 运行时的情况下在 Swift 中按名称实例化类

python - 动态属性分配

sql - PowerShell:如何确定SQL查询是否返回0行

sql - 在 SQL Server 上插入更新存储过程

SQL Server : How can I copy data from one table to another table without the characters 'e+' being added to the results

sql - 从最后两个方括号中提取数据 SQL

c# - 动态应用程序的 MS SQL 表结构

sql-server - 如何以所有者和唯一用户的身份修复 Azure SQL Server 中的数据库权限?