我有一个sql查询,它返回在会议中注册的学生列表,以及他们对每个会话的首选项。从数据库中提取数据时,每个用户会话选择都显示在其自己的行中,如下所示:
**userid question answer**
1 S1 choose: a1, b1, c1 a1
1 S2 choose: a2, b2, c2 b2
1 S3 choose: a3, b3, c3 b3
2 S1 choose: a1, b1, c1 b1
2 S2 choose: a2, b2, c2 c2
2 S3 choose: a3, b3, c3 a3
3 S1 choose: a1, b1, c1 a1
3 S2 choose: a2, b2, c2 b2
3 S3 choose: a3, b3, c3 b3
我想让每个会话成为一个列,以便每个带有问题和答案的用户ID显示在一行中。像这样:
user1 question1 answer1 question2 answer2 question3 answer3
user2 question1 answer1 question2 answer2 question3 answer3
user3 question1 answer1 question2 answer2 question3 answer3
我仅限于我的SQL查询知识,所以我非常感谢您的帮助....我如何才能达到上述结果? 提前致谢
答案 0 :(得分:0)
在回答您的评论时,如果您知道潜在问题的数量,则可以选择max
使用case
:
select userid,
max(case when questionid = 1 then question end) question1,
max(case when questionid = 1 then answer end) answer1,
max(case when questionid = 2 then question end) question2,
max(case when questionid = 2 then answer end) answer2,
...
from yourtable
group by userid
这假设您有questionid
可用。如果没有,您可以使用question
字段或创建ROW_NUMBER
,它的工作方式相同:
select userid,
max(case when rn = 1 then question end) question1,
max(case when rn = 1 then answer end) answer1,
max(case when rn = 2 then question end) question2,
max(case when rn = 2 then answer end) answer2,
...
from (
select *, row_number() over (partition by userid order by question) rn
from yourtable
) t
group by userid
编辑,如果您需要动态解决方案,因为您尝试pivot
多个列,首先需要取消结果。执行此操作的一个选项是使用CROSS APPLY
。然后你可以PIVOT
结果:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME('Question:' + question) +',' + QUOTENAME('Answer:' + question)
from yourtable
group by question
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'select userid, ' + @cols + '
from
(
select userid,
col+question new_col,
value
from yourtable
cross apply
(
VALUES
(question, ''Question:''),
(answer, ''Answer:'')
) x (value, col)
) src
pivot
(
max(value)
for new_col in (' + @cols + ')
) piv '
execute(@query)
答案 1 :(得分:0)
使用动态SQL。在您使用标识列创建的临时表中选择一个不同的会话列表。
DECLARE @SQL varchar(1000), @Count int, @Counter int
CREATE TABLE #report (userid int)
CREATE TABLE #questions (MyIdx int IDENTITY(1,1), question varchar(50))
INSERT INTO #report (UserID) SELECT DISTINCT userid from mytable
INSERT INTO #questions (question) SELECT DISTINCT question FROM mytable ORDER BY question
SELECT @Count = COUNT(*) FROM #questions, @Counter = 0
WHILE @Counter < @Count
BEGIN
SET @Counter = @Counter + 1
SET @SQL = 'ALTER TABLE #report ADD Q' + CONVERT(varchar, @Counter) + ' varchar(50)'
EXEC (@SQL)
SET @SQL = 'ALTER TABLE #report ADD A' + CONVERT(varchar, @Counter) + ' varchar(50)'
EXEC (@SQL)
SET @SQL = 'UPDATE #report SET Q' + CONVERT(varchar, @Counter) + ' = b.question FROM #report a INNER JOIN mytable b ON a.userid = b.userid INNER JOIN #questions c ON b.question = c.question WHERE c.MyIdx = ' + CONVERT(varchar, @Counter)
EXEC (@SQL)
SET @SQL = 'UPDATE #report SET A' + CONVERT(varchar, @Counter) + ' = b.answer FROM #report a INNER JOIN mytable b ON a.userid = b.userid AND a.question = b.Q' + CONVERT(varchar, @Counter)
EXEC (@SQL)
END
SELECT * FROM #report ORDER BY userid
DROP TABLE #report
DROP TABLE #questions
也就是说,如果你有不明数量的会话。否则,请另外回答。
答案 2 :(得分:0)
如果问题中的示例与您的数据类似,则可能是拆分和联合
SELECT userid
, q1 = max(q1), a1 = max(a1)
, q2 = max(q2), a2 = max(a2)
, q3 = max(q3), a3 = max(a3)
FROM (SELECT userid
, q1 = question, a1 = answer
, q2 = NULL, a2 = NULL
, q3 = NULL, a3 = NULL
FROM table1
WHERE left(question, 2) = 'S1'
UNION ALL
SELECT userid
, q1 = NULL, a1 = NULL
, q2 = question, a2 = answer
, q3 = NULL, a3 = NULL
FROM table1
WHERE left(question, 2) = 'S2'
UNION ALL
SELECT userid
, q1 = NULL, a1 = NULL
, q2 = NULL, a2 = NULL
, q3 = question, a3 = answer
FROM table1
WHERE left(question, 2) = 'S3') d
GROUP BY userid
每个问题代码用于分割数据,而另一个属性a用于所需列。每个数据拆分都有userid
,因此它可以用作锚点,用于对其他值进行分组,以便将映射减少到每userid
一行。