Подтвердить что ты не робот

MySQL оставил внешнее соединение с предложением where - возвращает несогласованные строки

У меня есть две таблицы: pq и pe. Я пытаюсь LEFT OUTER JOIN левую таблицу (pq) в правой таблице ( pe).

  • pq имеет идентификатор столбца первичного ключа
  • pe имеет двухколоночный первичный ключ, поэтому он может иметь много pqid или none
  • pe. Условный столбец должен использоваться для извлечения только релевантных данных (WHERE pe.uid = "12345")
  • pe.data следует присоединять к каждой строке pq.id

Вот как выглядят таблицы:

pq:
id | data
1  | "abc"
2  | "efg"

pe:
pqid | uid   | data
2    | 54321 | "uvw"
2    | 12345 | "xyz"

Я могу использовать следующий запрос для совпадения первых двух строк pq.id с pe.pqid

SELECT pq.id, pq.data, pe.data FROM pq
    LEFT OUTER JOIN pe ON pq.id = pe.pqid
    ORDER BY pq.id LIMIT 2

Я получаю:

pq.id | pq.data |  pe.data
1     | "abc"   |  
2     | "efg"   |  "uvw"

Но если я использую инструкцию WHERE следующим образом:

SELECT pq.id, pq.data, pe.data FROM pq
    LEFT OUTER JOIN pe ON pq.id = pe.pqid
    WHERE pe.uid='12345'
    ORDER BY pq.id LIMIT 2

Я получаю только одну строку с совпадением pe.pqid AND pe.uid:

pq.id | pq.data |  pe.data
2     | "efg"   |  "xyz"

Итак, с предложением WHERE я получаю правильные pe.data, но я не получаю строки pq, у которых нет pq. id pe.pqid

Мне нужно это сделать:

pq.id | pq.data |  pe.data
1     | "abc"   |  
2     | "efg"   |  "xyz"
4b9b3361

Ответ 1

Да. Предложение where превращает левое внешнее соединение во внутреннее соединение.

Почему? Значение pe.pqid равно NULL (as pe.uid), когда нет совпадения. Таким образом, сравнение в предложении where не выполняется (почти все сравнения с NULL return NULL, который считается ложным).

Решение состоит в том, чтобы переместить сравнение в предложение on:

SELECT pq.id, pq.data, pe.data
FROM pq LEFT OUTER JOIN
     pe
     ON pq.id = pe.pqid and
        pe.uid='12345'
ORDER BY pq.id LIMIT 2