Sql 每个唯一id返回1行,而不是多行

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

我有一个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查询知识有限,因此非常感谢您的帮助……我如何才能获得上述结果?
提前感谢

在回复您的评论时,假设您知道潜在问题的数量,一个选项是使用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