Home > Back-end >  Dynamic Pivot Tables based on Dates
Dynamic Pivot Tables based on Dates

Time:10-24

I need some assistance pivoting my data in SQL Server. I have tried several online PIVOTs but they either are for static values or aggregate the data somehow which I don't want. Ideally I want to return the data based on the project id and flip it so I can present in a different way.

My current table stores data like this:

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

My desired output when selecting Project Id = 1 would be:

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

My desired output when selecting Project Id = 2 would be:

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

Any assistance/links would be much appreciated.

CodePudding user response:

This is a pretty custom requirement, and I'm not surprised you haven't found a ready-made sample to copy and paste that fits your exact needs.

You can see post revisions for previous solutions but I think this is my favorite:

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
  • Example When ProductID is 2

    When ProductID is 1

  • Related