Как выбрать только те записи, которые не пересекаются и только те, которые пересеклись?
Есть таблица с полями: 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 = ? |
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 = ?
Дополнительно:
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` |
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 |
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
- Второе думаю подходит. Первое, слегка не то, что я хотел, но спасибо. В основном цель вопроса выполнена.
Ответы:
Используем [NOT] EXISTS
SELECT * FROM user_friend uf1 WHERE [NOT] EXISTS ( SELECT NULL FROM user_friend uf2 WHERE uf2.friend_user_id = uf1.user_id ) |
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.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для выборки записей, которые не пересекаются, и записей, которые пересеклись, можно использовать операторы SQL для работы с диапазонами дат. Предположим, у нас есть таблица "events" с колонками "start_date" и "end_date", которые содержат начальную и конечную даты событий.
Чтобы выбрать только те записи, которые не пересекаются, можно воспользоваться следующим запросом:
SELECT * FROM events WHERE end_date '2022-12-31';
Этот запрос выберет все записи, у которых дата окончания мероприятия раньше начала 2022 года или дата начала мероприятия после окончания 2022 года.
Чтобы выбрать только те записи, которые пересеклись с заданным диапазоном дат, можно воспользоваться следующим запросом:
SELECT * FROM events WHERE start_date = '2022-01-01';
Этот запрос выберет все записи, у которых дата начала мероприятия раньше или равна концу 2022 года и дата окончания мероприятия после или равна началу 2022 года.
Таким образом, используя операторы сравнения и логические операторы в SQL, можно легко выбрать нужные записи из таблицы, учитывая их временные интервалы.