У меня возникла проблема, чтобы исключить элементы в моем MySQL-запросе. Я хочу получить всех животных, которые не имеют никакого отношения к "Азии", например
Мои таблицы выглядят так.
Table 'animals'
+----+--------------+
| id | name |
+----+--------------+
| 1 | Tiger |
| 2 | Lion |
| 3 | Spider |
| 4 | Bird |
+----+--------------+
Таблица "Континент"
+----+--------------+
| id | name |
+----+--------------+
| 1 | Europe |
| 2 | Asia |
| 3 | Africa |
+----+--------------+
Таблица "отношения"
+----+--------+-----------+
| id | animal | continent |
+----+--------+-----------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 2 | 2 |
| 4 | 2 | 3 |
| 5 | 3 | 3 |
| 6 | 4 | 2 |
+----+--------+-----------+
Вот как выглядит мой запрос:
SELECT a.'id',
a.'name'
FROM a.'animals' AS a
LEFT JOIN 'relations' AS r
ON r.'animal' = a.'id'
WHERE r.'continent' != 2
ORDER BY a.'name' asc;
Проблема состоит в том, что это дает мне следующий результат:
Lion
Spider
Tiger
Дело в том, что "Лев" имеет отношение к континенту Азии (ID 2) и не должен быть в результатах. Не могли бы вы помочь мне решить эту проблему?
Используйте NOT EXISTS
чтобы показать только этих животных, для которых нет никакого отношения к азиатскому континенту:
select a.*
from animals a
where not exists (
select 1
from relations r
join continent c on
c.id = r.continent
where c.name = 'Asia'
and a.id = r.animal
)
select a.* from animal A where a.id not in(select animal from relations where continent=2);
Asia
, а не произвольное значение идентификатора.
Вы получаете лион, потому что у вас есть лев (id 2) в таблице отношений для континента ASIA
может быть, вам нужно животное, которое только для меня является континентом для азии, тогда
SELECT a.'id',
a.'name'
FROM a.'animals' AS a
LEFT JOIN 'relations' AS r
ON r.'animal' = a.'id'
WHERE r.'continent' != 2
AND a.id not in (
select animal from relation where continent = 2
)
ORDER BY a.'name' asc;
Один вариант использует предложение EXISTS
:
SELECT
a.id, a.name
FROM animals a
WHERE NOT EXISTS (SELECT 1 FROM relations r INNER JOIN continent c
ON r.continent = c.id
WHERE a.id = r.animal AND c.name = 'Asia');
Идея здесь заключается в том, что для каждого животного мы сканируем таблицу relations
соединенную с continent
поисках того же животного, которое назначено на азиатский континент. Если мы не сможем найти эти отношения, сохраните это конкретное животное.
Это потому, что у Льва есть связь с другой страной, которая не является Азией. Что вы хотите сделать:
SELECT a.id, a.name
FROM animals a
WHERE a.id NOT IN (
SELECT DISTINCT r.animal FROM relations r WHERE r.continent = 2
)
ORDER BY a.name DESC;
;)