SQL内部联接和分组

时间:2014-01-04 23:24:35

标签: sql sql-server inner-join

自从我完成SQL以来已经有一段时间了,但我有一个相当紧迫的问题。

我的db-layout如下:enter image description here

现在,从Users.ID开始,我希望获得用户播放的所有Rounds。用户可以是Hosts.HostIDHost.GuestID,也可以是两者。如果他是两者,则不应在结果中显示操作。

我在查询中需要的结果是Hosts.Name以及Rounds的所有字段。一般来说,我想要做的是显示用户参与的所有Hosts(实际上这些是游戏)的列表,作为主持人或访客,以及可能的总分。单击此按钮时,会出现一些下拉列表,显示各个圆形分数,单词......

现在我想知道在单个查询中这是否可行。当然,我可以查询获取所有Hosts然后每HostRound的查询,但这似乎并不符合要求。这是我到目前为止所提出的:

SELECT  Rounds.ID, Rounds.GameID, Rounds.Round, Rounds.Score, Rounds.Word
        , Hosts.ID, Hosts.HostID, Hosts.GuestID 
FROM    Rounds INNER JOIN Hosts 
ON      Rounds.GameID = Hosts.ID 
INNER JOIN Users 
ON     Hosts.hostID = Users.ID 
WHERE  Users.ID = 5

但问题是,它不会过滤掉用户同时是主机和来宾的位置,而且我似乎也无法按Hosts.ID对其进行分组。

2 个答案:

答案 0 :(得分:1)

Hosts.hostID <> Hosts.guestID添加到where子句。

答案 1 :(得分:0)

如果您使用的是SQL Server 2005或更高版本,则可以像这样修改当前查询:

SELECT  Rounds.ID, Rounds.GameID, Rounds.Round, Rounds.Score, Rounds.Word
        , Hosts.ID, Hosts.HostID, Hosts.GuestID 
FROM    Rounds INNER JOIN Hosts 
ON      Rounds.GameID = Hosts.ID 
CROSS APPLY
        (
        SELECT Hosts.HostID
        UNION
        SELECT Hosts.GuestID
        ) AS u (UserID)
WHERE   u.UserID = 5
;

CROSS APPLY子句将产生一行或两行,具体取决于HostIDGuestID是否相等。在任何一种情况下,WHERE条件最多都会留下一个。因此,上述查询只会为您提供指定用户参与的游戏(包括所有轮次)。

从那个查询中你可以很容易地得到这样的东西:

SELECT  Hosts.ID,
        TotalScore = SUM(Rounds.Score)
FROM
        ...
GROUP BY
        Hosts.ID
;