2012-04-02 1 views
2

У меня есть следующие таблицы:SQL заявление, что заказы выбраны идентификаторы первого с условием

team_members

userid 
teamid 

пользователей

uid 
name_f 
name_l 

друзья

friend_id 
friend_one 
friend_two 

Я использую следующий оператор для выбора uid и profile_pic пользователей, которые принадлежат определенной команде.

SELECT DISTINCT u.uid, u.profile_pic 
FROM friends f, users u, team_members m 
WHERE m.teamid =$team_var 
AND u.uid = m.userid 

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

SELECT DISTINCT u.uid, u.profile_pic 
FROM friends f, users u, team_members m 
WHERE m.teamid =$team_var 
AND u.uid = m.userid 
AND m.userid = f.friend_two 
AND f.friend_one =$session_id 

Я ищу способ, чтобы присоединиться к этим два и вместо запуска 2 запросов, выполнить один единственный запрос, который можно заказать и список пользователей, которые с друзьями вошедшего в систему пользователя в верхней части. Итак, предположим, что в определенной команде есть 30 пользователей, и 5 из этих пользователей являются друзьями с зарегистрированным пользователем, я бы хотел, чтобы первые 5, перечисленные в цикле while, следуя за заявлением, были такими же, как у друзей с остальной частью 25 случайным образом показаны.

Спасибо за ваше время.

+0

В таблице сопоставления друзей у вас есть логическое дублирование для friend_one и friend_two, таких как {{x, y}, {y, x}}? –

+0

Да, я делаю Тим. Это делается следующим образом, чтобы записать соединение друга (5 и 10 являются идентификаторами пользователя): friend_one: 5 friend_two: 10 - friend_one: 10 friend_two: 5 – user1011713

+0

Если у кого есть предложения, пожалуйста, дайте мне знать ... Я ' Очень сильно застрял на этом. – user1011713

ответ

1

Это легко решить с помощью внешнего соединения. Вероятно, вы не сможете использовать внешнее соединение без явного синтаксиса соединения. Здесь:

SELECT 
    u.uid, 
    u.profile_pic, 
    (friend_id IS NOT NULL) AS is_friend 
FROM team_members m 
    INNER JOIN users u ON m.userid = u.uid 
    LEFT JOIN friends f ON m.userid = f.friend_two AND f.friend_one = $session_id 
WHERE m.teamid = $team_var 
ORDER BY 
    is_friend DESC, 
    m.userid 

Первые две таблицы соединяются с помощью внутреннего соединения, поэтому только члены конкретной команды возвращаются (потому что мы фильтрация teamid).

Таблица friends внешняя сторона соединена с результатом предыдущего соединения. Более конкретно, мы присоединяемся к подмножеству от friends, где friend_one является текущим пользователем. Все строки из предыдущего результирующего набора возвращаются, а также строки из подмножества friends возвращаются туда, где они сопоставляются.Если не согласовано, столбцы friends заполняются NULL с.

Используя тест NULL (или, скорее, NOT NULL), мы можем видеть, какой член команды является другом, а какой нет. Результат теста возвращается как столбец, а также используется в качестве критерия сортировки для выходных строк.

+0

Ничего себе. Так оно и было. Спасибо огромное! – user1011713

+0

В чем разница между 'internal join' и' join' и что вы имеете в виду с 'external join'? Я думал, что мы просто имеем 'left join' или' right join' в mysql, а не 'external join'. – TMS

+0

@ Томас: 'INNER JOIN' и' JOIN' означают то же самое, ключевое слово 'INNER' является необязательным. Внешнее соединение [в MySQL] (http://dev.mysql.com/doc/refman/5.6/en/join.html «JOIN Syntax (MySQL)») является либо «LEFT JOIN», и «RIGHT JOIN». Их полные имена: «LEFT OUTER JOIN» и «RIGHT OUTER JOIN», поэтому, как вы можете видеть, «OUTER» также является необязательным, но даже без слова «OUTER» они все еще являются внешними соединениями. –

0

Вам нужно будет создать еще один столбец, который имеет значение «друг» или нет «друг». Затем вы использовали бы этот столбец как ORDER BY. Созданный столбец может быть подзапросом, чтобы определить, является ли другой пользователь другом или нет. Следующий код является неправильным, потому что вам нужно подключить данные из внешнего запроса в подзапрос, но это должно выглядеть примерно так:

SELECT DISTINCT u.uid, u.profile_pic, 
EXISTS (SELECT DISTINCT u.uid, u.profile_pic 
FROM friends f, users u, team_members m 
WHERE m.teamid =$team_var 
AND u.uid = m.userid 
AND m.userid = f.friend_two 
AND f.friend_one =$session_id 
) AS myColumn 
FROM friends f, users u, team_members m 
WHERE m.teamid =$team_var 
AND u.uid = m.userid 
ORDER BY myColumn 
+0

Для друзей, у меня есть таблица друзей. И это записывает friend_one с userid и friend_two с идентификатором пользователя второго пользователя, поэтому он будет избыточным, кажется, создает другой столбец для значения друга. – user1011713

0

Я мог бы предположить, что это:

select u.uid, u.profile_pic 
from team_members t 
    join team_members m on t.teamid = m.teamid 
    join users u on m.userid = u.uid 
    left join friends f on t.userid = f.friend_one and m.userid = f.friend_two 
where m.userid != t.userid 
    and t.userid = $session_id -- This line can be removed to view all (test) 
order by 
    --t.teamid, t.userid, -- This line can be added to order all (test) 
    (case when f.friend_id is null then 1 else 0 end case), 
    f.friend_id, m.userid 

Я использую явный синтаксис соединения (который обычно рекомендуется в эти дни) и использование этого оператора case в порядке, чтобы подружиться с друзьями. У меня нет MySQL, чтобы протестировать его, но синтаксис должен быть довольно стандартным (я запускаю что-то очень похожее на SQL Server).

+0

Я вижу. Где я буду играть в team_variable в этом случае? – user1011713

+0

Это не должно быть лишним, если только кто-то не может быть в одной команде. –

+0

Вот как это настроить прямо сейчас. Так, например, пользовательский Билл может посмотреть на 10 команд, и каждая команда будет иметь разных членов с друзьями в каждом. – user1011713

Смежные вопросы