Sql 每个唯一id返回1行,而不是多行
我有一个sql查询,它返回参加会议的学生列表,以及他们对每个会议的偏好。从“我的数据库”中提取数据时,每个用户会话选择都显示在其自己的行中,如下所示:Sql 每个唯一id返回1行,而不是多行,sql,sql-server,Sql,Sql Server,我有一个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
**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查询知识有限,因此非常感谢您的帮助……我如何才能获得上述结果?
提前感谢在回复您的评论时,假设您知道潜在问题的数量,一个选项是使用max with case: 这假设您有一个可用的questionid。如果没有,您可以使用“问题”字段或创建一个行号,其工作方式相同:
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结果。执行此操作的一个选项是使用交叉应用。然后,您可以将结果转回来:
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)
使用动态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
也就是说,如果会话数未知。否则,请使用另一个答案。如果问题中的示例与您的数据相似,则可能需要拆分和合并
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一行。您使用的是哪种RDBMS?您知道问题的数量吗?还是动态的?我正在使用Microsoft SQL Server Management Studio 2008。每次会议的问题数量各不相同。此外,使用演示代码(如.net、coldfusion等)通常更容易做到这一点。您可以使用这些代码吗?您应该使用常规编程语言执行输出格式化,并对结果进行迭代。您正在尝试将2列(共3行)合并为6列(共1行)。。。这不是查询语言的逻辑转换。@DanBracuk我现在没有可用的表示代码。Thakns@sgeddes。目前,我正在非动态地创建它们,但很快就必须使用动态SQL。
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