SQL Server:将多行数据转换为一行

时间:2017-11-28 18:43:41

标签: sql-server

我有下表,当初始设置为true和false时,我希望每个用户(userId)获得一行Answer列值。所以下表

UserId                              QuestionId   Answer  Initial
----------------------------------------------------------------
027D76AC-DFBC-4BD2-9B88DD7B2456338E 1            5       False
027D76AC-DFBC-4BD2-9B88DD7B2456338E 1            4       True
06B1713D-2E47-4454-8949C950C58753DC 1            4       True
216F33EF-1ACD-4D1F-86D2932AF598326E 1            5       False
216F33EF-1ACD-4D1F-86D2932AF598326E 1            4       True
23A950EB-3C68-4FE7-B719B86DC299343D 1            4       True
23A950EB-3C68-4FE7-B719B86DC299343D 1            4       False

会返回以下结果

UserId                              QuestionId   trueAnswer FalseAnswer
-----------------------------------------------------------------------
027D76AC-DFBC-4BD2-9B88DD7B2456338E 1            5          4
216F33EF-1ACD-4D1F-86D2932AF598326E 1            5          4
23A950EB-3C68-4FE7-B719B86DC299343D 1            4          4

这可以通过子选择来完成吗?

2 个答案:

答案 0 :(得分:1)

我认为下面可以是一个解决方案(顶部只是创建一个临时表来测试它)。我一直是避免GROUP BY的倡导者,而且我认为OUTER / CROSS APPLY非常酷。请注意,结果与结果相反。例如,你的最高者显示FalseAnswer为4.根据数据,它是5.除非我遗漏了什么。

-- creating sample set
IF object_id('tempdb..#YOUR_TABLE') is not null drop table #YOUR_TABLE
CREATE TABLE #YOUR_TABLE (UserID VARCHAR(200), QuestionID INT, Answer INT, Initial BIT)
INSERT INTO #YOUR_TABLE(UserID, QuestionID, Answer, Initial)
Values
('027D76AC-DFBC-4BD2-9B88DD7B2456338E', 1,            5,       'false'),
('027D76AC-DFBC-4BD2-9B88DD7B2456338E', 1,            4,       'true'),
('06B1713D-2E47-4454-8949C950C58753DC', 1,            4,       'true'),
('216F33EF-1ACD-4D1F-86D2932AF598326E', 1,            5,       'false'),
('216F33EF-1ACD-4D1F-86D2932AF598326E', 1,            4,       'true'),
('23A950EB-3C68-4FE7-B719B86DC299343D', 1,            4,       'true'),
('23A950EB-3C68-4FE7-B719B86DC299343D', 1,            4,       'false')

-- solution
SELECT a.UserID,
       a.QuestionID,
       a.Answer,
       b.FalseAnswer
FROM #YOUR_TABLE AS a
     OUTER APPLY
     (
        SELECT y.Answer AS FalseAnswer
        FROM #YOUR_TABLE AS y
        WHERE y.Initial='false' AND a.UserID=y.UserID
     ) AS b
WHERE a.Initial='true' AND b.FalseAnswer IS NOT null

输出

UserID  QuestionID  Answer  FalseAnswer
027D76AC-DFBC-4BD2-9B88DD7B2456338E 1   4   5
216F33EF-1ACD-4D1F-86D2932AF598326E 1   4   5
23A950EB-3C68-4FE7-B719B86DC299343D 1   4   4

答案 1 :(得分:0)

试试这个:

select UserID,
       max(QuestionID),
       max(case when Initial = 'True' then Answer end) [trueAnswer],
       max(case when Initial = 'False' then Answer end) [falseAnswer]
from TABLE_NAME
group by UserID
having count(distinct Initial) = 2