2013-06-19 2 views
1

У меня есть следующий запрос, который в настоящее время возвращает 2 строки (он всегда будет возвращать только 2 строки).SQL Объедините несколько строк из одной таблицы в одну строку с разными полями

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), но строки с одним и тем же бойлом нужно будет объединить, как в таблице, которую вы видите выше. Возможно ли это в SQL Server 2008?

ответ

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 
0

Вы могли бы сделать что-то похожее на ниже, где вы объявляете первоначальный выбор, а затем присоединиться к нему обратно на себя, где различие между иденты

;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 
Смежные вопросы