我正在寻找一种纯SQL方式(SQL Server 2012,如果重要的话)将行数据转换为列。我试过搜索这个,但是找不到我想要转换的数据格式的东西,可能是因为我的SQL知识非常基础。
我的输入数据是从我们的JIRA服务器中提取的版本名称和故事点列表,以及提取日期。我试图使用的表实际上包含来自许多不同项目的提取,尽管我从这些示例中排除了ProjectName列。
输入数据:
Version Date StoryPoints
1.0 2017-01-01 10
1.0 2017-02-01 10
1.0 2017-03-01 15
1.0 2017-04-01 15
2.0 2017-01-01 10
2.0 2017-02-01 10
2.0 2017-03-01 10
2.0 2017-04-01 10
3.0 2017-01-01 5
3.0 2017-02-01 5
3.0 2017-03-01 5
3.0 2017-04-01 5
Completed 2017-01-01 0
Completed 2017-02-01 5
Completed 2017-03-01 15
Completed 2017-04-01 28
我们需要以下面任一格式生成一个表格,用于在Confluence wiki中创建“燃尽”图表。由于每个项目可以具有不同的版本名称,因此我们无法对下面的任何列名称进行硬编码(尽管“已完成”将存在于所有项目中)。
此外,即使我们将标准化类似于示例中的日期,我也不希望将任何日期值硬编码到查询中。
输出格式#1:
Date 1.0 2.0 3.0 Completed
2017-01-01 10 10 5 0
2017-02-01 10 10 5 5
2017-03-01 15 10 5 15
2017-04-01 15 10 5 28
我认识到以这种方式构建数据可能很困难,因此也可以使用以下输出格式,我也可以在Confluence中绘制图表(虽然它不像上面的格式那样直观)。
输出格式#2:
Versions 2017-01-01 2017-02-01 2017-03-01 2017-04-01
1.0 10 10 15 15
2.0 10 10 10 10
3.0 5 5 5 5
Completed 0 5 15 28
非常感谢任何帮助!
答案 0 :(得分:2)
SQL Server 2012要求您将要转移的维度之一硬编码到PIVOT query中。
解决这个问题的一种方法是构建并执行动态query string。
答案 1 :(得分:2)
正如刘星洲所说,我想到了这一点。
来源:
IF ( OBJECT_ID('tempdb..#TMPtbl') IS NOT NULL )
BEGIN
DROP TABLE #TMPtbl
END
CREATE TABLE #TMPtbl
(
Id INT IDENTITY(1, 1)
PRIMARY KEY ,
[Version] VARCHAR(10) ,
[Date] DATETIME ,
StoryPoints INT
)
INSERT INTO #TMPtbl
( Version, Date, StoryPoints )
VALUES ( '1.0', '2017-01-01', 10 ),
( '1.0', '2017-02-01', 10 ),
( '1.0', '2017-03-01', 15 ),
( '1.0', '2017-04-01', 15 ),
( '2.0', '2017-01-01', 10 ),
( '2.0', '2017-02-01', 10 ),
( '2.0', '2017-03-01', 10 ),
( '2.0', '2017-04-01', 10 ),
( '3.0', '2017-01-01', 5 ),
( '3.0', '2017-02-01', 5 ),
( '3.0', '2017-03-01', 5 ),
( '3.0', '2017-04-01', 5 ),
( 'Completed', '2017-01-01', 0 ),
( 'Completed', '2017-02-01', 5 ),
( 'Completed', '2017-03-01', 15 ),
( 'Completed', '2017-04-01', 28 )
DECLARE @StrColVer NVARCHAR(MAX) = STUFF(( SELECT DISTINCT
', '
+ QUOTENAME(CAST(t.[Version] AS VARCHAR(154)))
FROM #TMPtbl t
FOR
XML PATH('')
), 1, 2, '')
DECLARE @StrColSUmVer NVARCHAR(MAX) = STUFF(( SELECT DISTINCT
', ' + 'SUM('
+ QUOTENAME(CAST(t.[Version] AS VARCHAR(154)))
+ ') '
+ QUOTENAME(CAST(t.[Version] AS VARCHAR(154)))
FROM #TMPtbl t
FOR
XML PATH('')
), 1, 2, '')
DECLARE @StrColDate NVARCHAR(MAX) = STUFF(( SELECT DISTINCT
', '
+ QUOTENAME(FORMAT(t.Date,
'yyyy-MM-dd'))
FROM #TMPtbl t
FOR
XML PATH('')
), 1, 2, '')
DECLARE @StrColSumDate NVARCHAR(MAX) = STUFF(( SELECT DISTINCT
', ' + 'SUM('
+ QUOTENAME(FORMAT(t.Date,
'yyyy-MM-dd'))
+ ') '
+ QUOTENAME(FORMAT(t.Date,
'yyyy-MM-dd'))
FROM #TMPtbl t
FOR
XML PATH('')
), 1, 2, '')
DECLARE @SQL1 NVARCHAR(MAX) = N'SELECT [Date],
' + @StrColSUmVer + '
FROM (
SELECT * FROM #TMPtbl
)P
PIVOT (
SUM(StoryPoints) FOR Version IN (' + @StrColVer + ')
)PVT
GROUP BY pvt.[Date]'
DECLARE @SQL2 NVARCHAR(MAX) = N'SELECT [Version],
' + @StrColSumDate + '
FROM (
SELECT * FROM #TMPtbl
)P
PIVOT (
SUM(StoryPoints) FOR dATE IN (' + @StrColDate + ')
)PVT
GROUP BY pvt.[Version]'
EXEC(@SQL1)
EXEC(@SQL2)
结果
Date 1.0 2.0 3.0 Completed
----------------------- ----------- ----------- ----------- -----------
2017-01-01 00:00:00.000 10 10 5 0
2017-02-01 00:00:00.000 10 10 5 5
2017-03-01 00:00:00.000 15 10 5 15
2017-04-01 00:00:00.000 15 10 5 28
(4 row(s) affected)
Version 2017-01-01 2017-02-01 2017-03-01 2017-04-01
---------- ----------- ----------- ----------- -----------
1.0 10 10 15 15
2.0 10 10 10 10
3.0 5 5 5 5
Completed 0 5 15 28
(4 row(s) affected)