2015-06-08 3 views
0

Я пытаюсь выбрать друзей текущего пользователя, используя запрос, который возвращает список друзей для таблицы 1 строка за дружбу.SQL Выбор запроса для друзей

У меня есть пользователь и Друзья таблица:

User(UserID, Username) 

Friends(IdFirst, IdSecond) 

Предполагая, что у меня есть следующие пользователи: (1, 'Alex'), (2, 'Ana'), (3, 'Daniel') и следующая дружба: (1, 2), (1,3), (2,3)

До сих пор я использую этот запрос:

SELECT * FROM User U 
LEFT JOIN Friends F 
ON U.IdUser = F.IdSecond 
WHERE F.IdFirst = *LOGGED USER ID* 

И это работает только в том случае, если у меня есть зеркальная дружба, например: (1, 2) (2, 1) (1, 3) (3,1), и я хочу только одного пара для каждой дружбы. Если использовать указанный выше запрос, я получаю только список друзей для IdFirst.

Надеюсь, у меня есть смысл, спасибо!

ответ

1

Как насчет союза? http://sqlfiddle.com/#!9/da447/7

SELECT * FROM users U 
    LEFT JOIN friends F 
    ON U.userid = F.idsecond 
    WHERE F.idfirst = *LOGGED USER ID* 
UNION 
SELECT * FROM users U 
    LEFT JOIN friends F 
    ON U.userid = F.idfirst 
    WHERE F.idsecond = *LOGGED USER ID* 
+0

Спасибо! Я забыл о союзах ... –

0

Почему бы не просто? Если вам не нужны поля от пользователей, которых вы не указали.

SELECT idFirst 
     ,idSecond 
    FROM Friends 
WHERE IdFirst = *LOGGED USER ID* 
    OR IdSecond =*LOGGED USER ID* 

Это означает, что вам не нужно иметь зеркальную дружбу - и на самом деле вы не должны.

EDIT: если вы хотите, чтобы пользователь для друзей, вы можете сделать это без союза как:

SELECT * 
    FROM users U 
WHERE UserID <> *LOGGED USER ID* 
    AND EXISTS(
       SELECT 1 
       FROM Friends 
       WHERE (IdFirst = *LOGGED USER ID* AND IdSecond = UserID) 
        OR (IdSecond =*LOGGED USER ID* AND IdFirst = UserID) 
      ) 

Я не уверен, что это лучше, чем @BarbaraLaird «s. Хотя план выполнения выглядит проще здесь http://sqlfiddle.com/#!9/da447/13

+0

Я мог ошибаться, но, похоже, он пытался получить имя всех друзей текущего пользователя. –

+0

@BarbaraLaird: Конечно, может быть, это не было явным. Если это, очевидно, потребуется больше, как вы полагаете. –

0

Прежде всего делать left join, а фильтрация с правой таблицы - это вздор, потому что левое соединение становится внутренним соединением. Во-вторых, вы можете сделать это с помощью соединений, нет необходимости в union:

select case when u1.Id = @currentUser then u1.Id else u2.Id end as Id, 
     case when u1.Id = @currentUser then u1.Name else u2.Name end as Name, 
from Friends f 
join Users u1 on f.IdFirst u1.Id 
join Users u2 on f.IdSecond u2.Id 
where u1.Id = @currentUser or u2.Id = @currentUser 
Смежные вопросы