Мой совет со сложными запросами всегда начать с простого:
# Find friends A and B
select A.email as A_email, A.name as A_name, B.email as B_email, B.name as B_name
from user A
join friends
on A.email = friends.friend1_email
join user B
on B.email = friends.friend2.email
достаточно просто, давайте делать это снова для B и C:
# Find friends B and C
select B.email as B_email, B.name as B_name, C.email as C_email, C.name as C_name
from user B
join friends
on B.email = friends.friend1_email
join user C
on C.email = friends.friend2.email
Теперь давайте объединимся, чтобы получить A, B и C в одном запросе
# Find friends A, B, and C
select A.email as A_email, A.name as A_name, B.email as B_email, B.name as B_name, C.email as C_email, C.name as C_name
from user A
join friends f1
on A.email = f1.friend1_email
join user B
on f1.friend2_email = B.email
join friends f2
on B.email = f2.friend1_email
join user C
on f2.friend2_email = C.email
Вышеприведенный запрос даст нам всех пользователей A, которые являются друзьями с пользователями B, которые являются друзьями с пользователями C, но не ограничивают набор результатов теми отчетами, в которых A и C не являются друзьями. Чтобы получить этот набор результатов, нам придется немного изменить наш запрос.
# Find friends A, B, and C
select A.email as A_email, A.name as A_name, B.email as B_email, B.name as B_name, C.email as C_email, C.name as C_name
from user A
join friends f1
on A.email = f1.friend1_email
join user B
on f1.friend2_email = B.email
join friends f2
on B.email = f2.friend1_email
join user C
on f2.friend2_email = C.email
left join friends f3
on A.email = f3.friend1_email
and C.email = f3.friend2_email
where
f3.friend1_email is null
Вы пытаетесь перемещаться по направленному графику? Если это так, это будет очень сложно сделать с чистым SQL, поскольку этот процесс часто является глубоко рекурсивным. – tadman
@tadman: глубокая рекурсивность не является проблемой SQL как таковой, потому что рекурсивные запросы уже были в стандарте SQL уже более десяти лет. Только MySQL все еще не может их выполнять. –
@a_horse_with_no_name Предоставлено SQL * standard * позволяет такие вещи, но это MySQL. – tadman