Использование 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 раз. Таким образом, количество Frame / Choice Description / DateTime для каждого UserID будет разным.
Я знаю, что должен использовать хранимую процедуру (или, может быть, даже макрос 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
<ч />
!! ОБНОВЛЕНИЕ !! Полное рабочее решение и тестовый код
<ч />
- Пример подготовки данных
ЗАЯВИТЬ @FrameChoices as TABLE (UserId varchar (50), Frame varchar (50), Choice varchar (4000), Описание varchar (1000), [DateTime] DateTime)
--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
- этот сгенерированный SQL затем может быть выполнен с помощью
EXEC(@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