SQL将同一个表中的多个行组合成一个具有不同字段的行

时间:2013-06-19 03:52:58

标签: sql sql-server sql-server-2008

我有以下查询当前返回2行(它总是只返回2行)。

Select
    User_Profile.userid, User_Profile.displayname, User_Profile.picPath,
    Battle.id as battleid, Battle.challenger_id as challengerid,
    Video.[filename]
From 
    Battle
INNER Join  
    User_Profile ON Battle.challenger_id = User_Profile.userid OR
                    Battle.challenged_id = User_Profile.userid
INNER Join
    Video ON User_Profile.userid = Video.[user_id]
WHERE
    Video.battle_id = Battle.id

返回如下内容:

userid | displayname | picPath  | battleid | challengerid | filename
--------------------------------------------------------------------
6      | CandyPoo   | test.jpg  |   12     | 9            | test.mp4
9      | Nawlrus    | test2.jpg |   12     | 9            | test2.mp4

我希望返回这样的内容:

battleid | challengerid | xuserid | xdisplayname | xpicPath  | xfilename | Yuserid | YdisplayName | YpicPath | YfileName
--------------------------------------------------------------------------------------------------------------------------
12       | 9            |  9      | Nawlrus      | test2.jpg | test2.mp4 | 6       | CandyPoo     | test.jpg | test.mp4

有没有办法做到这一点?我将返回多行,如上面的那一行(Top X),但具有相同battleid的行将需要像上面看到的表一样合并。这在SQL Server 2008中是否可行?

2 个答案:

答案 0 :(得分:1)

您声明您的查询将始终只返回两行。如果确实如此,那么您可以使用row_number()为每一行分配一个序列值,然后使用带有CASE表达式的聚合函数将行转换为列:

select battleid,
  challengerId,
  max(case when seq = 1 then userid end) xUserId,
  max(case when seq = 1 then displayname end) xDisplayName,
  max(case when seq = 1 then picPath end) xPicPath,
  max(case when seq = 1 then filename end) xFileName,
  max(case when seq = 2 then userid end) yUserId,
  max(case when seq = 2 then displayname end) yDisplayName,
  max(case when seq = 2 then picPath end) yPicPath,
  max(case when seq = 2 then filename end) yFileName
from
(
  Select User_Profile.userid, 
    User_Profile.displayname, 
    User_Profile.picPath,
    Battle.id as battleid, 
    Battle.challenger_id as challengerid,
    Video.[filename],
    row_number() over(partition by battle.id order by user_profile.userid) seq
  From Battle
  INNER Join User_Profile 
    ON Battle.challenger_id = User_Profile.userid 
    OR Battle.challenged_id = User_Profile.userid
  INNER Join Video 
    ON User_Profile.userid = Video.[user_id]
    AND Video.battle_id = Battle.id
) src
group by battleid, challengerId

答案 1 :(得分:0)

您可以执行与下面类似的操作,您可以在其中声明初始选择,然后将其连接回自身,以区分用户ID

;with
    GetData as
    (
        Select
        User_Profile.userid as userid, User_Profile.displayname as displayname
            ,User_Profile.picPath as picpath,
        Battle.id as battleid, Battle.challenger_id as challengerid,
        Video.[filename] as vfilename
        From Battle
        INNER Join  
        User_Profile ON Battle.challenger_id = User_Profile.userid OR
        Battle.challenged_id = User_Profile.userid
        INNER Join
        Video ON User_Profile.userid = Video.[user_id]
        WHERE
        Video.battle_id = Battle.id
    )
    SELECT battleid, challengerid
           ,a.userid as xuserid, a.displayname as xdisplayname, a.picpath as xpicpath
           ,a.vfilename as xfilename
           ,b.userid as yuserid, b.displayname as ydisplayname, b.picpath as ypicpath
           ,b.vfilename as yfilename
    FROM GetData a
    JOIN GetData b on a.battleid = b.battleid and a.userid != b.userid