使用SQL 2005 这是我的SQL结果的样子
UserID | Frame | Choice | Description | DateTime
------------------------------------------------
bcn005 | PL_P03| 1 | Rules-Based | 2011-10-24 14:14:26
bcn005 | PL_P04| 0 | VirtueBased | 2011-10-24 14:16:37
...
bmk172 | Prac_1| 0 | None | 2011-10-25 12:45:38
...
我的客户希望结果看起来像这样
UserID | Frame | Choice | Description | DateTime | Frame | Choice | Description | DateTime
-------------------------------------------------------------------------------------------
bcn005 | PL_P03| 1 | Rules-Based | 2011-10-..| PL_P04| 0 | VirtueBased | 2011-10-..
bmk172 | Prac_1| 0 | None | 2011-10-..|
所有参与者的回复都在一行中。对于结果集的每一行,基本上需要另一组Frame / Choice Description / DateTime。
这些是调查结果,但调查类型中有一位参与者可能已经回过头并改变了他们的答案5次。因此,每个UserID的Frame / Choice Description / DateTime的数量将不同。
我知道我应该使用存储过程(或者甚至是excel宏),但我对这两者都是全新的。任何指导表示赞赏。这是我的SQL查询
select UserID, locationName AS 'Frame', student_response AS 'Choice',
description, DateTime
from tblStudentResponses
WHERE GroupID in (18,20,21,36,37,38,39,40)
AND UserID in (SELECT UserID FROM tblStudentResponses WHERE
locationName = 'Character1Certificate')
AND DateTime > '2011-10-01'
AND type = 'choice'
order by UserID
<小时/> 的 !!更新!! 完整的工作解决方案和测试代码
--Test Values
INSERT INTO @FrameChoices(UserId,Frame,Choice,Description,[DateTime])
SELECT UserId,Frame,Choice,Description,[DateTime]
FROM (
SELECT 'bcn005' AS UserId, 'PL_P03' AS Frame, '1' AS Choice, 'Rules-Based'
AS Description, '2011-10-24 14:14:26' AS [DateTime]
UNION ALL
SELECT 'bcn005' AS UserId, 'PL_P04' AS Frame, '0' AS Choice, 'VirtueBased'
AS Description, '2011-10-24 14:16:37' AS [DateTime]
UNION ALL
SELECT 'bmk172' AS UserId, 'Prac_1' AS Frame, '0' AS Choice, 'None' AS
Description, '2011-10-25 12:45:38' AS [DateTime]
) T
- 动态SQL准备
DECLARE @SQL VARCHAR(MAX)
DECLARE @MaxNumberOfFrames INT
SET @SQL = ''
SET @MaxNumberOfFrames = 1
SELECT @MaxNumberOfFrames = MAX(FrameCount)
FROM
(
SELECT COUNT(1) FrameCount
FROM @FrameChoices
GROUP BY UserId
) T
--needed to be part of the SQL string to EXEC at the bottom
SET @SQL = 'DECLARE @FrameChoices as TABLE(UserId varchar(50),Frame varchar(50),Choice varchar(4000),Description varchar(1000),[DateTime] DateTime)'
SET @SQL = @SQL + ' INSERT INTO @FrameChoices(UserId,Frame,Choice,Description,[DateTime])'
SET @SQL = @SQL + ' SELECT UserId,Frame,Choice,Description,[DateTime]'
SET @SQL = @SQL + ' FROM ('
SET @SQL = @SQL + ' SELECT ''bcn005'' AS UserId, ''PL_P03'' AS Frame, ''1'' AS Choice, ''Rules-Based'''
SET @SQL = @SQL + ' AS Description, ''2011-10-24 14:14:26'' AS [DateTime]'
SET @SQL = @SQL + ' UNION ALL'
SET @SQL = @SQL + ' SELECT ''bcn005'' AS UserId, ''PL_P04'' AS Frame, ''0'' AS Choice, ''VirtueBased'''
SET @SQL = @SQL + ' AS Description, ''2011-10-24 14:16:37'' AS [DateTime]'
SET @SQL = @SQL + ' UNION ALL'
SET @SQL = @SQL + ' SELECT ''bmk172'' AS UserId, ''Prac_1'' AS Frame, ''0'' AS Choice, ''None'' AS'
SET @SQL = @SQL + ' Description, ''2011-10-25 12:45:38'' AS [DateTime]'
SET @SQL = @SQL + ' ) T'
SET @SQL = @SQL + ' SELECT UserId'
--changed size to max
DECLARE @ColumnSQL VARCHAR(MAX)
DECLARE @CurrentFrame INT
SET @CurrentFrame = 1
WHILE (@CurrentFrame <= @MaxNumberOfFrames)
BEGIN
SET @ColumnSQL = ', MAX(CASE WHEN RowNumber ='+CAST(@CurrentFrame AS VARCHAR)+ ' THEN Frame ELSE '''' END) AS Frame_'+CAST(@CurrentFrame AS VARCHAR)
+ ', MAX(CASE WHEN RowNumber ='+CAST(@CurrentFrame AS VARCHAR)+ ' THEN Choice ELSE '''' END) AS Choice_'+CAST(@CurrentFrame AS VARCHAR)
+ ', MAX(CASE WHEN RowNumber ='+CAST(@CurrentFrame AS VARCHAR)+ ' THEN Description ELSE '''' END) AS Description_'+CAST(@CurrentFrame AS VARCHAR)
+ ', MAX(CASE WHEN RowNumber ='+CAST(@CurrentFrame AS VARCHAR)+ ' THEN [DateTime] ELSE NULL END) AS DateTime_'+CAST(@CurrentFrame AS VARCHAR)
SET @SQL = @SQL + @ColumnSQL
SET @CurrentFrame = @CurrentFrame + 1
END
SET @SQL = @SQL + ' FROM ( SELECT UserId,Frame,Choice,Description,[DateTime], ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY [DateTime]) AS RowNumber FROM @FrameChoices) T GROUP BY T.UserId'
PRINT @SQL
- 然后可以通过
执行生成的SQLEXEC(@SQL)
-- OR
EXEC SP_EXECUTESQL(@SQL)
- 从上面的查询生成的示例SQL
DECLARE @FrameChoices as TABLE(UserId varchar(50),Frame varchar(50),Choice varchar(4000),Description varchar(1000),[DateTime] DateTime) INSERT INTO @FrameChoices(UserId,Frame,Choice,Description,[DateTime]) SELECT UserId,Frame,Choice,Description,[DateTime] FROM ( SELECT 'bcn005' AS UserId, 'PL_P03' AS Frame, '1' AS Choice, 'Rules-Based' AS Description, '2011-10-24 14:14:26' AS [DateTime] UNION ALL SELECT 'bcn005' AS UserId, 'PL_P04' AS Frame, '0' AS Choice, 'VirtueBased' AS Description, '2011-10-24 14:16:37' AS [DateTime] UNION ALL SELECT 'bmk172' AS UserId, 'Prac_1' AS Frame, '0' AS Choice, 'None' AS Description, '2011-10-25 12:45:38' AS [DateTime] ) T SELECT UserId, MAX(CASE WHEN RowNumber =1 THEN Frame ELSE '' END) AS Frame_1, MAX(CASE WHEN RowNumber =1 THEN Choice ELSE '' END) AS Choice_1, MAX(CASE WHEN RowNumber =1 THEN Description ELSE '' END) AS Description_1, MAX(CASE WHEN RowNumber =1 THEN [DateTime] ELSE NULL END) AS DateTime_1, MAX(CASE WHEN RowNumber =2 THEN Frame ELSE '' END) AS Frame_2, MAX(CASE WHEN RowNumber =2 THEN Choice ELSE '' END) AS Choice_2, MAX(CASE WHEN RowNumber =2 THEN Description ELSE '' END) AS Description_2, MAX(CASE WHEN RowNumber =2 THEN [DateTime] ELSE NULL END) AS DateTime_2 FROM ( SELECT UserId,Frame,Choice,Description,[DateTime], ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY [DateTime]) AS RowNumber FROM @FrameChoices) T GROUP BY T.UserId
答案 0 :(得分:1)
如果是SQL 2005或ABove,您可以尝试使用pivot。
如果是SQL 2000,则使用Group By和Case的组合。
SELECT GC1,
GC2,
MAX(CASE WHEN CONDITION1 THEN Value1 ELSE Value2 END) AS DerivedColumn
FROM Table1
GROUP BY GC1, GC2
参考文献: SQL Server PIVOT and UNPIVOT
[解决]
- 样本数据准备
DECLARE @FrameChoices TABLE
(
UserId varchar(20),
Frame varchar(20),
Choice int,
Description varchar(20),
[DateTime] DateTime
)
INSERT INTO @FrameChoices(UserId,Frame,Choice,Description,[DateTime])
SELECT UserId,Frame,Choice,Description,[DateTime]
FROM (
SELECT 'bcn005' AS UserId, 'PL_P03' AS Frame, 1 AS Choice, 'Rules-Based' AS Description, '2011-10-24 14:14:26' AS [DateTime]
UNION ALL
SELECT 'bcn005' AS UserId, 'PL_P04' AS Frame, 0 AS Choice, 'VirtueBased' AS Description, '2011-10-24 14:16:37' AS [DateTime]
UNION ALL
SELECT 'bmk172' AS UserId, 'Prac_1' AS Frame, 0 AS Choice, 'None' AS Description, '2011-10-25 12:45:38' AS [DateTime]
) T
- 动态SQL准备
DECLARE @SQL VARCHAR(4000)
DECLARE @MaxNumberOfFrames INT
SET @SQL = ''
SET @MaxNumberOfFrames = 1
SELECT @MaxNumberOfFrames = MAX(FrameCount)
FROM
(
SELECT COUNT(1)FrameCount
FROM @FrameChoices
GROUP BY UserId
) T
SET @SQL = 'SELECT UserId'
DECLARE @ColumnSQL VARCHAR(512)
DECLARE @CurrentFrame INT
SET @CurrentFrame = 1
WHILE (@CurrentFrame <= @MaxNumberOfFrames)
BEGIN
SET @ColumnSQL = ', MAX(CASE WHEN RowNumber ='+CAST(@CurrentFrame AS VARCHAR)+ ' THEN Frame ELSE NULL END) AS Frame_'+CAST(@CurrentFrame AS VARCHAR)
+ ', MAX(CASE WHEN RowNumber ='+CAST(@CurrentFrame AS VARCHAR)+ ' THEN Choice ELSE NULL END) AS Choice_'+CAST(@CurrentFrame AS VARCHAR)
+ ', MAX(CASE WHEN RowNumber ='+CAST(@CurrentFrame AS VARCHAR)+ ' THEN Description ELSE NULL END) AS Description_'+CAST(@CurrentFrame AS VARCHAR)
+ ', MAX(CASE WHEN RowNumber ='+CAST(@CurrentFrame AS VARCHAR)+ ' THEN [DateTime] ELSE NULL END) AS DateTime_'+CAST(@CurrentFrame AS VARCHAR)
SET @SQL = @SQL + @ColumnSQL
SET @CurrentFrame = @CurrentFrame + 1
END
SET @SQL = @SQL + ' FROM ( SELECT UserId,Frame,Choice,Description,[DateTime], ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY [DateTime]) AS RowNumber FROM @FrameChoices) T GROUP BY T.UserId'
PRINT @SQL
- 然后可以通过
执行生成的SQLEXEC(@SQL)
-- OR
EXEC SP_EXECUTESQL(@SQL)
- 从上面的查询生成的示例SQL
SELECT UserId, MAX(CASE WHEN RowNumber =1 THEN Frame ELSE NULL END) AS Frame_1, MAX(CASE WHEN RowNumber =1 THEN Choice ELSE NULL END) AS Choice_1, MAX(CASE WHEN RowNumber =1 THEN Description ELSE NULL END) AS Description_1, MAX(CASE WHEN RowNumber =1 THEN [DateTime] ELSE NULL END) AS DateTime_1, MAX(CASE WHEN RowNumber =2 THEN Frame ELSE NULL END) AS Frame_2, MAX(CASE WHEN RowNumber =2 THEN Choice ELSE NULL END) AS Choice_2, MAX(CASE WHEN RowNumber =2 THEN Description ELSE NULL END) AS Description_2, MAX(CASE WHEN RowNumber =2 THEN [DateTime] ELSE NULL END) AS DateTime_2 FROM ( SELECT UserId,Frame,Choice,Description,[DateTime], ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY [DateTime]) AS RowNumber FROM @FrameChoices) T GROUP BY T.UserId
答案 1 :(得分:0)
您想要的是SQL Server的数据透视表功能
http://msdn.microsoft.com/en-us/library/ms177410(SQL.90).aspx