MySQL: выбрать страницы, которые не помечены? - PullRequest
0 голосов
/ 10 февраля 2011

У меня есть БД с двумя таблицами, как показано ниже,

таблица страниц

pg_id    title
1        a
2        b
3        c
4        d

помеченная таблица

tagged_id   pg_id
1           1
2           4

Я хочу выбрать страницы с тегами. Я пытался выполнить этот запрос ниже, но он не работает,

SELECT *
FROM root_pages
LEFT JOIN root_tagged ON ( root_tagged.pg_id =  root_pages.pg_id )
WHERE root_pages.pg_id !=  root_tagged.pg_id

Возвращает ноль - Showing rows 0 - 1 (2 total, Query took 0.0021 sec)

Но яхотите, чтобы он возвращал

pg_id    title
    2        b
    3        c

Мой запрос должен быть неверным?
Как я могу вернуть страницы, которые не были помечены правильно?

Ответы [ 2 ]

2 голосов
/ 10 февраля 2011
SELECT *
FROM root_pages
LEFT JOIN root_tagged ON root_tagged.pg_id = root_pages.pg_id
WHERE root_tagged.pg_id IS NULL

Оператор != (или <>) сравнивает два значения, но не может использоваться для NULL.

  • NULL = NULL возвращает false
  • NULL = 0 возвращает false
  • NULL! = NULL возвращает false

Вы получаете точку, для проверки на NULL вы должны использовать оператор IS или IS NOT.

1 голос
/ 10 февраля 2011

Если ваша плотность тегов на страницах превышает 2: 1 или около того, использование NOT EXISTS будет быстрее, чем использование LEFT JOIN + IS NULL

SELECT *
FROM root_pages
WHERE NOT EXISTS (
    SELECT *
    FROM root_tagged
    WHERE root_tagged.pg_id =  root_pages.pg_id )

Это альтернатива, которая более четко заявляет, что вы ищете, небытие.

Для зачеркнутого текста выше:
Вопрос специфичен для MySQL, и, предполагая, что root_tagged.pg_id не имеет значения nullable, LEFT JOIN + IS NULL реализован с использованием ANTI-JOIN, которая является той же стратегией, что и NOT EXISTS, за исключением того, что кажется, что некоторые издержки добавлены NOT EXISTS, поэтому LEFT JOIN должен работать быстрее.

...