Как сделать SQL JOIN с исключением

У меня есть 3 таблицы:

  1. пользователи [id, name]
  2. черный список [blockerid, blockedid]
  3. местоположение [uuid, lat, lon]

Мне нужно получить все данные из таблицы местоположений с условием, что если человек, который запрашивает местоположение, представлен в черном списке как блокировщик или заблокирован, не увидит это запрещенное местоположение. Например:

Blacklist:
10 11

Location
10 74.1231 51.12312
11 82.1231 -1.31241
12 10.2121 34.12312

если 12 запрашивают местонахождение, он получает все. если 11 запрашивает местоположение, он получит только местоположение 12, то же самое, что и 10.

Нужна помощь в запросе

Можете ли вы предоставить лучший пример данных со всеми задействованными таблицами (пользователи, черный список и местоположение) и разместить их на sqlfiddle.com? А также обеспечить более ожидаемые результаты на основе данных примера для условий «если 12 запрашивает местоположение, он получает все. Если 11 запрашивает местоположение, он получит только местоположение 12, то же самое, что и 10».

Raymond Nijland 28.04.2018 17:40
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
1
69
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете использовать объединение для получения как blockerid, так и blockedid в качестве идентификатора для not in

  select * 
  from localtion 
  where uuid not in ( 
        select blockerid as my_id
        from (
            select  blockerid,  blockedid
            from  Blacklist
            where   blockerid = your_id
            or   blockedid = your_id 
        ) AS alias
        union 
        select blockedid
        from (
            select  blockerid,  blockedid
            from  Blacklist
            where   blockerid = your_id
            or   blockedid = your_id 
        ) AS alias

  )

@RaymondNijland .. спасибо за (правильное) редактирование .. голосование где-то

scaisEdge 28.04.2018 18:14

Я настоятельно рекомендую разбить запрос следующим образом:

select l.*
from location l
where not exists (select 1 from blocklist bl where bl.blockerid = l.uuid and bl.blockedid = ?) and
      not exists (select 1 from blocklist bl where bl.blockedid = l.uuid and bl.blockerid = ?);

? - это заполнитель для идентификатора пользователя, который вас интересует.

Это может использовать преимущества двух индексов на blocklist, blocklist(blockerid, blockedid) и blocklist(blockedid, blockerid) для значительного увеличения производительности.

Другие вопросы по теме