2012-02-21 97 views
0

我在SQL Server 2008中的表有以下字段如何在SQL Server 2008中查询两个相同的值?

RoomUserId->Primary key 
RoomId->Foreign Key of Table Rooms 
UserId->Foreign Key of Table Users 

现在我有值以下,其中RoomId是常见的两个用户

RoomUserId RoomId UserId 
     1  11 1 
     2  11 2 
     3  12 1 
     4  12 3 
     5  13 1 
     6  13 4 

现在我需要一个SQL查询来发现两个用户不同的是roomid。即用户1和用户2的roomid,用户1和用户3的用户2,roomid

任何人都可以帮助我,因为我是SQL Server的新手。

回答

0

试试这个:

SELECT r1.roomId FROM room r1 JOIN room r2 ON r1.roomId = r2.roomId WHERE r1.userId = 1 AND r2.userId = 3 
0

如果你的意思是找到一个roomid是共同的用户:

select distinct f.roomid 
from rooms f 
inner join rooms s on f.roomid = s.roomid and f.userid <> s.userid 

或者你可以用分组:

select roomid 
from rooms 
group by roomid 
having count(distinct userid) > 1 
0

如果你只有永远需要有多个用户的房间,那么这将工作:

SELECT DISTINCT RoomID 
FROM RoomUser r1 
     INNER JOIN RoomUser r2 
      ON r1.RoomID = r2.RoomID 
      AND r1.RoomUserID != r2.RoomUserID 

如果您需要包含x个用户的房间的房间ID,则使用Having子句,这比自己加入的子项更具可扩展性。如果你需要找房的ID有3个或更多的用户ID,那么你最终会得到:

SELECT RoomID 
FROM RoomUser 
GROUP BY RoomID 
HAVING COUNT(DISTINCT UserID) > 3 

而使用自联接,而可能更有效地将结束与一些相当混乱SQL。检查执行计划并运行一些测试,以查看哪些更适合您的需求。

如果你确实需要在房间的用户的用户ID与多个用户ID,那么你可以使用一个CTE建立一个逗号分隔的用户的字符串中的每个房间:

;WITH RoomUserCTE AS 
( SELECT RoomID, 
      MIN(UserID) [UserID], 
      CONVERT(VARCHAR(20), MIN(UserID)) [Users], 
      0 [Recursion] 
    FROM RoomUser 
    GROUP BY RoomID 
    UNION ALL 
    SELECT a.RoomID, 
      b.UserID [UserID], 
      CONVERT(VARCHAR(20), Users + ', ' + CONVERT(VARCHAR, b.UserID)), 
      Recursion + 1 
    FROM RoomUserCTE a 
      INNER JOIN RoomUser b 
       ON a.RoomID = b.RoomID 
       AND b.UserID > a.UserID 
) 
SELECT RoomID, Users 
FROM ( SELECT *, MAX(Recursion) OVER(PARTITION BY RoomID) [MaxRecursion] 
      FROM RoomUserCTE 
     ) cte 
WHERE MaxRecursion = Recursion 

对于数据在你的问题,这将产生

| RoomID | Users | 
|---------+---------| 
| 11  | 1, 2 | 
| 12  | 1, 3 | 
| 13  | 1, 4 | 

这无论工作多用户ID是如何与同一房间ID相关联,因此又更向前兼容。