MySQL выбирает строки, где левое соединение равно null

У меня есть эти таблицы MySQL:

table1:

id | writer
1  | Bob   
2  | Marley
3  | Michael

table2:

user_one | user_two
   1     | 2

И этот запрос:

SELECT table1.id FROM table1 LEFT JOIN table2 ON table1.id = table2.user_one

Этот запрос вернет все строки таблицы1, которые составляют 1,2,3

Я хочу выбрать только строки, которые не найдены в левом суставе. Поэтому он должен возвращать только строку с id 3

Мне нужна противоположность INNER JOIN, которая будет выбирать только строки, которые находятся в соединении. Как получить противоположное, как если бы левое соединение существовало, игнорировать его и перейти к следующей строке. Надеюсь, я понятен.

Ответы

Ответ 1

Вы можете использовать следующий запрос:

SELECT  table1.id 
FROM    table1 
        LEFT JOIN table2 
            ON table1.id IN (table2.user_one, table2.user_two)
WHERE   table2.user_one IS NULL;

Хотя, в зависимости от ваших индексов на table2, вы можете обнаружить, что два соединения работают лучше:

SELECT  table1.id 
FROM    table1 
        LEFT JOIN table2 AS t1
            ON table1.id = t1.user_one
        LEFT JOIN table2 AS t2
            ON table1.id = t2.user_two
WHERE   t1.user_one IS NULL
AND     t2.user_two IS NULL;

Ответ 2

Один из лучших подходов, если вы не хотите возвращать столбцы из table2, - это использовать NOT EXISTS

SELECT  table1.id 
FROM    table1 T1
WHERE
  NOT EXISTS (SELECT *
              FROM table2 T2
              WHERE T1.id = T2.user_one
                  OR T1.id = T2.user_two)

Семантически это говорит о том, что вы хотите запросить: выберите каждую строку, в которой нет соответствующей записи во второй таблице.

MySQL оптимизирован для EXISTS: он возвращает, как только он находит первую соответствующую запись.

Ответ 3

Вот запрос, который возвращает только строки, в которых не было найдено совпадений в обоих столбцах user_one и user_two of table2:

SELECT T1.*
FROM table1 T1
LEFT OUTER JOIN table2 T2A ON T2A.user_one = T1.id
LEFT OUTER JOIN table2 T2B ON T2B.user_two = T1.id
WHERE T2A.user_one IS NULL
    AND T2B.user_two IS NULL

Для каждого столбца существует одно соединение (user_one и user_two), и запрос возвращает только строки, которые не имеют подходящей совместной работы.

Надеюсь, это поможет вам.

Ответ 4

Try:

SELECT A.id FROM
(
  SELECT table1.id FROM table1 
  LEFT JOIN table2 ON table1.id = table2.user_one
  WHERE table2.user_one IS NULL
) A
JOIN (
  SELECT table1.id FROM table1 
  LEFT JOIN table2 ON table1.id = table2.user_two
  WHERE table2.user_two IS NULL
) B
ON A.id = B.id

См. Демо

Или вы можете использовать два LEFT JOINS с псевдонимами вроде:

SELECT table1.id FROM table1 
 LEFT JOIN table2 A ON table1.id = A.user_one
 LEFT JOIN table2 B ON table1.id = B.user_two
 WHERE A.user_one IS NULL
 AND B.user_two IS NULL

См. 2-е демо

Ответ 5

Попробуйте выполнить следующий запрос: -

 SELECT table1.id 
 FROM table1 
 where table1.id 
 NOT IN (SELECT user_one
         FROM Table2
             UNION
         SELECT user_two
         FROM Table2)

Надеюсь, это поможет вам.

Ответ 6

SELECT table1.id 
FROM table1 
LEFT JOIN table2 ON table1.id = table2.user_one
WHERE table2.user_one is NULL