Запрос MySQL, адресованный трем таблицам: сколько из A не находится в B или C? - PullRequest
2 голосов
/ 20 февраля 2012

У меня проблема с формулировкой запроса MySQL для выполнения следующей задачи, хотя я видел подобные запросы, обсуждаемые здесь, они достаточно отличаются от этого, чтобы снукировать мои попытки их транспонировать.Проблема (довольно) проста в изложении.У меня есть три таблицы: «members», «dog_shareoffered» и «dog_sharewanted».Участники могут иметь ноль, одну или несколько рекламных объявлений о вещах, которые они хотят продать или хотят купить, и данные хранятся в соответствующей таблице предлагаемых или разыскиваемых товаров вместе с идентификатором участника, который разместил объявление.Столбец id уникален для члена и является общим для всех трех таблиц.Я хочу спросить, сколько участников НЕ разместили рекламу ни в одной из таблиц.

Я пробовал несколько способов задать этот вопрос.Самое близкое, что я могу получить, это запрос, который не падает!(Я не эксперт MySQL в любом случае).Следующее, что я собрал из того, что я почерпнул из других примеров, но возвращает ноль строк, где я знаю, что результат должен быть больше нуля.

SELECT id 
  FROM members 
 WHERE id IN (SELECT id 
                FROM dog_sharewanted 
               WHERE id IS NULL) 
   AND id IN (SELECT id 
                FROM dog_shareoffered 
               WHERE id IS NULL)

Этот запрос выглядит довольно простым для понимания, в отличие от«JOIN» я видел, но думаю, что, возможно, мне нужен какой-то тип Join, но как это будет выглядеть в этом случае?

1 Ответ

6 голосов
/ 20 февраля 2012

Если вы не хотите показывать объявления в таблице или , то запрос, который вам нужен, следующий:

SELECT id
FROM members
WHERE id NOT IN ( any id from any other table )

Чтобы выбрать идентификаторы из других таблиц:

SELECT id
FROM <othertable>

Таким образом:

SELECT id
FROM members
WHERE id NOT IN (SELECT id FROM dog_shareoffered)
 AND  id NOT IN (SELECT id FROM dog_sharewanted)

Я добавил «SELECT DISTINCT», потому что один участник может разместить много объявлений, но есть только один идентификатор. Раньше у меня было SELECT DISTINCT в подзапросах выше, но, как отмечается в комментариях ниже, не обязательно.

Если вы хотите избежать подзапроса (возможное увеличение производительности в зависимости от ..), вы можете использовать ЛЕВЫЕ СОЕДИНЕНИЯ:

SELECT members.id
FROM members
LEFT JOIN dog_shareoffered
 ON dog_shareoffered.id = members.id
LEFT JOIN dog_sharewanted
 ON dog_sharewanted.id = members.id
WHERE dog_shareoffered.id IS NULL
  AND dog_sharewanted.id IS NULL

Почему это работает:

Он берет таблицу members и присоединяет ее к двум другим таблицам в столбце id. LEFT JOIN означает, что если элемент существует в таблице members, но не таблицы, к которой мы присоединяемся (например, dog_shareoffered), то соответствующие столбцы dog_shareoffered будут иметь NULL в них.

Итак, условие WHERE выбирает строки, в которых есть NULL id как в dog_shareoffered, так и dog_sharewanted, что означает, что мы нашли идентификаторы в members без соответствующего идентификатора в двух других таблицах.

...