Как найти элементы без связи с таблицей MySQL

0

У меня возникла проблема, чтобы исключить элементы в моем 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) и не должен быть в результатах. Не могли бы вы помочь мне решить эту проблему?

  • 0
    у вас есть идентификатор льва 2 в таблице отношений для континента 1
Теги:
foreign-keys

5 ответов

1

Используйте 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
)
0
select a.* from animal A where a.id not in(select animal from relations where continent=2);
  • 0
    Я думаю, что ОП хотел бы использовать в запросе имя континента Asia , а не произвольное значение идентификатора.
  • 0
    Итак, мы можем написать это следующим образом: выберите a. * Из животного A, где a.id нет в (выберите животное из отношений r соедините континент c на c.id = r.continent, где c.name = 'Asia' и a. id = r.animal);
Показать ещё 1 комментарий
0

Вы получаете лион, потому что у вас есть лев (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;
  • 0
    @KamilG. .. спасибо за правильное предложение ..
  • 0
    .. @KamilG. , просто неправильный набор в любом случае уже проголосовал за ваш ответ за спасибо предложение
0

Один вариант использует предложение 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');

Изображение 174551

демонстрация

Идея здесь заключается в том, что для каждого животного мы сканируем таблицу relations соединенную с continent поисках того же животного, которое назначено на азиатский континент. Если мы не сможем найти эти отношения, сохраните это конкретное животное.

  • 0
    Не приведет ли это к снижению производительности, поскольку таблица становится все больше и больше?
  • 0
    Проблема производительности по сравнению с какой альтернативой? Без сравнения моего решения с другим подходом ваш вопрос не имеет смысла. Ответ, который я дал, должен быть по крайней мере таким же эффективным, как и подход к объединению. Другой подход, который приходит на ум, - это агрегация, но в этом случае, если вы посмотрите, что СУБД придется сделать, чтобы получить ответ, он будет очень похож на ответ, который я дал.
Показать ещё 3 комментария
0

Это потому, что у Льва есть связь с другой страной, которая не является Азией. Что вы хотите сделать:

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;

;)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню