2014-01-04 5 views
1

Прошло некоторое время с тех пор, как я сделал SQL, но у меня есть довольно насущная проблема.SQL Inner Join and Grouping

Мой дб-раскладка выглядит следующим образом: enter image description here

Теперь, начиная с Users.ID, я хочу, чтобы получить все Rounds пользователь играл. Пользователь может быть Hosts.HostID, Host.GuestID, или даже оба. Если он оба, он не должен показывать op в результатах.

Результаты, которые мне нужны из запроса, это Hosts.Name и все поля Rounds. В общем, что я хочу сделать, это отобразить список всех Hosts (на самом деле это Игры), в которых пользователь участвовал, как Хост или Гость, а также, возможно, общий балл. При нажатии на это вы увидите раскрывающийся список, показывающий отдельные баллы, слова, ...

Теперь мне было интересно, возможно ли это в одном запросе. Конечно, я мог бы сделать запрос, получая все Hosts, а затем за Host запрос для каждого Round, но это не похоже на то, что исполнитель. Это то, что я придумал до сих пор:

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 или.

ответ

1

Добавить Hosts.hostID <> Hosts.guestID в предложение where.

+0

И что бы это достичь? Разве это не просто * исключает * пользователей, которые являются как хостом, так и гостем? –

+0

Нет, это исключало бы хосты, в которых пользователь является как хостом, так и гостем. – Andres

+0

Да, хозяева, вот что я имел в виду, извините. Главное, однако, что они будут исключать эти строки «Хосты» полностью, в то время как OP, похоже, хочет их выбрать, просто не дублируйте результаты как для «HostID», так и «GuestID», когда они ссылаются на одного пользователя. –

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 
;

Поперечное ОТНОСИТЬСЯ положение будет производить один или два ряда, в зависимости от того, HostID и GuestID являются равны. В любом случае условие WHERE в конечном счете оставит не более одного. Таким образом, вышеупомянутый запрос даст вам только игры (со всеми их раундами), в которых участвовал указанный пользователь.

И из этого запроса вы можете легко получить что-то вроде этого:

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