Выберите строки, не соответствующие указанному значению (несколько записей) - PullRequest
1 голос
/ 24 марта 2020

У меня есть таблица с изображениями вроде

imageID  imageName
12223    my nice image #1 
12224    my nice image #2
12225    my nice image #3

таблица с категориями

categoryID  categoryName
110         animals 
111         cars 
112         food 

и таблица image_to_category с

imageID  categoryID
12223    110
12223    111
12224    110
12225    112

я сейчас хочу выберите все изображения NOT в категории 110. Технически это возможно только в предложении where более сложного запроса. Поэтому мое первое намерение состояло в том, чтобы использовать

... WHERE imageID IN (SELECT imageID FROM _image_to_category WHERE categoryID NOT IN (110))

, но это работает, только если изображение имеет 110 в качестве единственной категории. Если изображение относится к двум разным категориям, оно явно не будет работать.

Можно ли сгруппировать выделение в предложении where? Или какие-нибудь другие идеи?

thx.

1 Ответ

0 голосов
/ 24 марта 2020

Мы можем использовать шаблон анти-объединения.

Мы можем написать запрос, который получает все изображения, с внешним объединением, чтобы найти совпадающие строки в image_to_category с categoryID 110. Затем мы можем исключить все строки, у которых есть совпадение ...

SELECT i.imageid
     , i.imagename
  FROM images i
    -- anti-join 
  LEFT
  JOIN image_to_category c 
    ON c.imageid    = i.imageid
   AND c.categoryid = 110 
 WHERE c.imageid IS NULL
    --
 ORDER BY ...

Мы можем получить эквивалентный результат с помощью коррелированного подзапроса NOT EXISTS

SELECT i.imageid
     , i.imagename
  FROM images i
 WHERE NOT EXISTS 
       ( SELECT 1
           FROM image_to_category c
          WHERE c.imageid    = i.imageid
            AND c.categoryid = 110 
       ) 
 ORDER BY ...

Это всего лишь два шаблона. Существуют другие шаблоны запросов, которые будут возвращать эквивалентный результат.

...