Задать вопрос
@Sparkis
PHP Developer

Как выбрать только те записи, которые не пересекаются и только те, которые пересеклись?

Есть таблица с полями: user_id, friend_user_id.

В таблице от каждого пользователя добавляются записи о подписке. Мол user_id подписан на user_friend_id и если в таблице 2 записи перекрестной, то такие пользователи уже считаются друзьями.

Вопросы стоят такие:
1. Как из таблицы выбрать только перекрёстные записи, т.е. Юзер1 подписан на Юзер2 и Юзер2 подписан на Юзер1.
2. Как из таблицы выбрать только непересекающиеся записи. т.е. те записи, где первый пользователь подписан на другого, но другой НЕ подписан на первого.

Сразу скажу на счет второй части вопроса, я нашел ответ, но действительно ли правильное решение?

SELECT DISTINCT a.user_id
FROM user_friend a INNER JOIN user_friend b
ON a.friend_user_id = b.user_id
    AND b.friend_user_id <> a.user_id
WHERE a.user_id = ?
  • Вопрос задан
  • 372 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
1.
SELECT `t1`.*
  FROM `table` AS `t1`
  JOIN `table` AS `t2` ON `t2`.`user_id` = `t1`.`friend_user_id`
    AND `t2`.`friend_user_id` = `t1`.`user_id`

2.
SELECT `t1`.*
  FROM `table` AS `t1`
  JEFT JOIN `table` AS `t2` ON `t2`.`user_id` = `t1`.`friend_user_id`
    AND `t2`.`friend_user_id` = `t1`.`user_id`
  WHERE `t2`.`user_id` IS NULL
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Akina
Сетевой и системный админ, SQL-программист.
Используем [NOT] EXISTS
SELECT *
FROM user_friend uf1
WHERE [NOT] EXISTS ( SELECT NULL
                     FROM user_friend uf2
                     WHERE uf2.friend_user_id = uf1.user_id )

При WHERE EXISTS выбираются пары друзей (записи, имеющие обратную пару), при WHERE NOT EXISTS - записи, не имеющие обратной пары.

Если для записей, имеющих обратную, нужна только одна пара из двух - добавляем во WHERE внешнего запроса ещё одно условие AND friend_user_id > user_id.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы