Вы можете выбрать пользователей, которые дружат с обоими пользователями, дважды связав таблицу пользователей с таблицей зебры:
SELECT u.username, u.user_colour, u.username_clean, u.user_avatar, u.user_avatar_type
FROM users u
JOIN zebra z1 ON z1.friend=1 AND (
(u.user_id = z1.user_id AND z1.zebra_id = @user_id1)
OR (u.user_id = z1.zebra_id AND z1.user_id = @user_id1)
)
JOIN zebra z2 ON z2.friend=1 AND (
(u.user_id = z2.user_id AND z2.zebra_id = @user_id2)
OR (u.user_id = z2.zebra_id AND z2.user_id = @user_id2)
)
ORDER BY u.username_clean ASC
JOIN
получает все строки от пользователейtable, и все строки из таблицы zebra, и ищет комбинации, которые удовлетворяют условию ON
.В этом случае первое объединение находит всех пользователей, которые являются друзьями с @user_id1
, второе объединение еще более ограничивает его пользователями, которые также являются друзьями с @user_id2
.
Этот запрос будет выполняться намного быстрее, чем использование подзапросовбудут.Запрос был бы еще быстрее, если бы таблица zebra
хранила дружеских отношений в обоих направлениях, позволяя вам использовать все преимущества табличных индексов, и вы могли бы удалить часть OR
предложений ON
:
SELECT u.username, u.user_colour, u.username_clean, u.user_avatar, u.user_avatar_type
FROM users u
JOIN zebra z1 ON u.user_id = z1.user_id AND z1.friend=1 AND z1.zebra_id = @user_id1
JOIN zebra z2 ON u.user_id = z2.user_id AND z2.friend=1 AND z2.zebra_id = @user_id2
ORDER BY u.username_clean ASC