Как получить результаты из таблицы MySQL, которые НЕ соответствуют двум другим таблицам

#mysql #sql

#mysql #sql

Вопрос:

Пытался разобраться с этим всю ночь и изо всех сил. Этот вопрос относится к базе данных MySQL.

Мне нужно SELECT все записи в одной таблице, которые НЕ отображаются в двух других таблицах.

Например, возьмите следующие таблицы:

таблица1

 | email     |  module | name    |
| a@ba.com  |  401    | Chris   |
| a@ba.com  |  402    | Chris   |
| a@ba.com  |  403    | Chris   |
| a@ba.com  |  404    | Chris   |
| a@ba.com  |  405    | Chris   |
| z@xy.com  |  401    | Anna    |
| z@xy.com  |  402    | Anna    |
| z@xy.com  |  403    | Anna    |
| z@xy.com  |  404    | Anna    |
| z@xy.com  |  405    | Anna    |
  

таблица2

 | email     | module | requested |
| a@ba.com  | 402    | Yes       |
| a@ba.com  | 403    | No        |
| z@xy.com  | 403    | Yes       |
  

table3

 | email     | module    | received |
| a@ba.com  | 405       | Yes      |
| z@xy.com  | 401       | No       |
| z@xy.com  | 404       | No       |
  

Мне нужно иметь возможность выполнять поиск по трем таблицам, чтобы найти записи, в которых совпадает адрес электронной почты. Затем я хотел бы выбрать все строки из table1 , где модуль уникален для этой таблицы, т. Е. Он не отображается ни в одной из двух других таблиц. Например, для пользователя по имени Крис я бы ожидал, что запрос вернет следующие результаты, поскольку два модуля (401 и 404) не отображаются ни в одной из двух других таблиц:

 | email     | module  | name   |
| a@ba.com  | 401     | Chris  |
| a@ba.com  | 404     | Chris  |
  

Я пробовал играть с разными типами JOIN фраз и провел большую часть вечера, пытаясь найти ответ на это, но безрезультатно. Может кто-нибудь здесь помочь?

Комментарии:

1. Помог ли вам какой-либо из ответов? если это так, пожалуйста, примите ту, которая помогла больше всего, как правильную. Спасибо!

Ответ №1:

LEFT JOIN должно обеспечить хорошую производительность в MySQL :

 SELECT t1.email
     , t1.module
     , t1.name
FROM table1 t1 LEFT JOIN table2 t2 ON t1.email = t2.email 
                                  AND t1.module = t2.module
               LEFT JOIN table3 t3 ON t1.email = t3.email
                                  AND t1.module = t3.module
WHERE t2.email IS NULL 
  AND t3.email IS NULL
  

Комментарии:

1. у t2 нет столбца name , как и у t3. Но в остальном я думаю, что вы правы

2. @Chausser: Спасибо

3. 1. Этот запрос (с использованием шаблона антисоединения) вернет все строки, из table1 которых «совпадающая» строка не найдена ни в table2 , ни table3 в. (Спецификация OP не ясна; первая часть спецификации есть, но в более позднем описании говорится «выполните поиск по трем таблицам, чтобы найти записи, в которых совпадает адрес электронной почты». Запрос в этом ответе возвращает строки из таблицы1, которые не совпадают, независимо от того, существует ли соответствующий адрес электронной почты в таблице2 и / или таблице3. (Возможно, из-за этой части спецификации у OP возникли трудности?)

4. @spencer7593 : Ну, может быть (я придерживался желаемого результата), давайте дождемся разъяснений OP.

Ответ №2:

Я думаю, вам нужно

 WHERE NOT EXISTS() 
  

предложение. Это вариант предложения EXISTS().

Ответ №3:

 SELECT x.* 
  FROM table1 x
  LEFT 
  JOIN
     ( SELECT * FROM table2
       UNION
       SELECT * FROM table3
     ) y
    ON y.email = x.email 
   AND y.module = x.module
 WHERE y.module IS NULL;