Ваше предложение where вызывает фильтрацию пустых строк. Рассмотрим упрощенную схему:
Таблица A
Col1 Col2
----------------
1 A
2 B
Таблица B
Col1 Col2
----------------
1 X
3 Y
И простое полное соединение без фильтр:
SELECT *
FROM TableA AS A
FULL JOIN TableB AS B
ON A.Col1 = B.Col1
который вернет
A.Col1 A.Col2 B.Col1 B.Col2
---------------------------------------
1 A 1 X
2 B NULL NULL
NULL NULL 3 Y
Теперь, если вы примените фильтр к чему-либо из A, например, WHERE A.Col1 = 1
, вы избавитесь от 2-й строки ( вероятно, как и предполагалось), начиная с 2 <> 1
, но вы также удалите 3-ю строку, поскольку A.Col
- это NULL
и NULL <> 1
. Поскольку вы удалили все строки без соответствующей записи в TableA
, вы фактически превратили свое полное соединение в левое соединение. Если вы затем примените дополнительный предикат к TableB
, ваше левое соединение станет внутренним соединением.
С Полными объединениями я считаю, что самое простое решение - применить ваши фильтры перед объединением, используя подзапросы, например:
SELECT *
FROM (SELECT * FROM TableA WHERE Col1 = 1) AS A
FULL JOIN TableB AS B
ON A.Col1 = B.Col1;
, который удаляет 2-ю строку, но все еще сохраняет 3-ю строку из предыдущих результатов:
A.Col1 A.Col2 B.Col1 B.Col2
---------------------------------------
1 A 1 X
NULL NULL 3 Y
Вы также можете использовать OR
, но чем больше у вас предикатов, тем более запутанным может быть, например,
SELECT *
FROM TableA AS A
FULL JOIN TableB AS B
ON A.Col1 = B.Col1
WHERE (Col1 = 1 OR A.Col1 IS NULL);