基于日期的动态数据透视表

Dynamic Pivot Tables based on Dates

我需要一些帮助来在 SQL 服务器中旋转我的数据。我已经尝试了几个在线 PIVOT,但它们要么用于静态值,要么以某种方式聚合我不想要的数据。理想情况下,我想 return 基于项目 ID 的数据并翻转它,以便我可以以不同的方式呈现。

我当前的 table 存储这样的数据:

Project Id Projected Month Labor Equipment
1 2021-09-01 500 0
1 2021-10-01 250 250
1 2021-11-01 100 50
2 2021-11-01 100 50
2 2021-12-01 100 50

选择项目ID = 1时我所需的输出将是:

2021-09-01 2021-10-01 2021-11-01
Labor 500 250 100
Equipment 0 250 50

选择项目ID = 2时我所需的输出将是:

2021-11-01 2021-12-01
Labor 100 50
Equipment 100 50

任何 assistance/links 将不胜感激。

这是一个非常自定义的要求,您没有找到适合您确切需要的现成示例来复制和粘贴我并不感到惊讶。

您可以看到 post 对以前解决方案的修订,但我认为这是我最喜欢的:

CREATE PROCEDURE dbo.DoThePivotThing
  @ProjectId int
AS
BEGIN
  DECLARE @cols nvarchar(max), 
          @agg  nvarchar(max),
          @sql  nvarchar(max);

  SELECT @cols = STUFF((SELECT ',
  ' + QUOTENAME([Projected Month])
    FROM dbo.Projects WHERE [Project Id] = @ProjectId
    FOR XML PATH(''), TYPE).value
    (N'./text()[1]', N'nvarchar(max)'),1,1,'');

  SELECT @agg = STUFF((SELECT ',
  ' + QUOTENAME([Projected Month]) 
    + ' = MAX(' + QUOTENAME([Projected Month]) + N')'
    FROM dbo.Projects WHERE [Project Id] = @ProjectId
    FOR XML PATH(''), TYPE).value
    (N'./text()[1]', N'nvarchar(max)'),1,1,'');

  SET @sql = N';WITH x AS (
    SELECT * FROM dbo.Projects 
    CROSS APPLY (VALUES(1,''Labor'',Labor),
                   (2,''Equipment'',Equipment)) AS v(o,t,v)
    PIVOT (MAX(v) FOR [Projected Month] 
        IN (' + @cols + ')
    ) AS piv
  )
  SELECT Cost = t, ' + @agg + N' FROM x GROUP BY t,o ORDER BY o;';

  EXEC sys.sp_executesql @sql, N'@ProjectId int', @ProjectId;
END
EXEC dbo.DoThePivotThing @ProjectId = 1;
Cost 2021-09-01 2021-10-01 2021-11-01
Labor 500 250 100
Equipment 0 250 50
EXEC dbo.DoThePivotThing @ProjectId = 2;
Cost 2021-11-01 2021-12-01
Labor 100 100
Equipment 50 50

我使用动态 sql 进行旋转以生成输出。这是一种方法,您可能会找到许多解决方案路径来达到您的输出。

  Create table Projects
   (
      ProjectID  int
      ,[ProjectedMonth] Date
      ,Labor Int
     ,Equipment int
   )
Insert into  Projects values (1,'2021-09-01', 500, 0)
 , (1,'2021-10-01', 250,250)
 , (1,'2021-11-01', 100,50)
 , (2,'2021-11-01', 100,50)
 , (2,'2021-12-01', 100,50)

 DECLARE @Project_Id AS VARCHAR(10) = '2'
 DECLARE @cols AS NVARCHAR(MAX), @query  AS NVARCHAR(MAX);

 SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(a.[ProjectedMonth]) 
    FROM  Projects [a]
    WHERE ProjectID = @Project_Id
    FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)') 
,1,1,'')


  Set @query = '
   SELECT ''Labor'' as [title], *   
       FROM   
         (select  labor,[ProjectedMonth]  from  Projects where CAST(ProjectID AS VARCHAR(10)) =' + @Project_Id +') p  
       PIVOT  
        (  MAX (labor)  
           FOR [ProjectedMonth] IN  
        ( ' + @cols+ ' )  
      ) AS pvt 
      
      UNION ALL
      
       SELECT ''Equipment'' as [title], *   
    FROM   
     (select  Equipment,[ProjectedMonth]  from  Projects where CAST(ProjectID AS VARCHAR(10)) =' + @Project_Id +') p  
    PIVOT  
      (  MAX (Equipment)  
        FOR [ProjectedMonth] IN  
      ( ' + @cols+ ' )  
      ) AS pvt   ;'



  --select @query
  EXEC sys.sp_executesql @query