基于日期的动态数据透视表
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
我需要一些帮助来在 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