2010-09-09 3 views
3

у меня есть два запроса, которые я думал, означал то же самое, но я получаем разные результаты, и я надеялся, что кто-то может объяснить, как они отличаются:Семантическая разница между запросами присоединиться

1.

select * 
from table1 a 
left join table2 b on a.Id = b.Id and a.val = 0 
where b.Id is null 

2.

select * 
from table1 a 
left join table2 b on a.Id = b.Id 
where b.Id is null 
    and a.val = 0 

точка запрос, чтобы найти те строки, которые находятся в таблица1 и Вале = 0, что не в table2.

Я также использую SQL Server 2008, но я сомневаюсь, что это имеет значение.

ответ

9

При рассмотрении левого соединения думают о них как о трех концептуальных этапах.

  1. Джойн фильтр применяется
  2. Левые строки добавляются обратно в
  3. в котором применяется пункт.

После этого вы увидите, почему вы получаете разные результаты.

Это также объясняет, почему это возвращает результаты

select o.* 
from sys.objects o 
left join sys.objects o2 on o.object_id=o2.object_id and 1=0 

И это не делает.

select o.* 
from sys.objects o 
left join sys.objects o2 on o.object_id=o2.object_id 
where 1=0 
1
SELECT * from TABLE1 t1 
    WHERE Val = 0 
    AND NOT EXISTS(SELEct 1 from Table2 t2 Where t1.Id = t2.Id) 
+0

Это не вернет ничего, если в обеих таблицах есть какой-либо идентификатор, так как существо всегда будет истинным. Я думаю, вы думаете о том, чтобы преобразовать соединение в крест, но просто не добрались до конца. –

1

Если вы удалите пункт WHERE полностью, используя LEFT OUTER JOIN означает, что будут отображаться все строки из таблицы на левой стороне, даже если они не удовлетворяют критериям JOIN. Например, ни одна строка не удовлетворяет выражению 1 = 0 однако это:

SELECT * 
    FROM table1 AS a 
     LEFT OUTER JOIN table2 AS b 
      ON a.Id = b.Id 
      AND 1 = 0; 

по-прежнему приводит всех строк в table1 возвращается, где матч id значения. Проще говоря, вот так работает OUTER JOIN.

Предложение WHERE применяется после JOIN, поэтому этот

SELECT * 
    FROM table1 AS a 
     LEFT OUTER JOIN table2 AS b 
      ON a.Id = b.Id 
WHERE 1 = 0; 

не вернет ни одной строки.

Смежные вопросы