道理很简单.4楼朋友说中了一部分..再补充一下,主要是a做为了基表,你又使用的left join. 所以先连表再 where 过滤时, 跟先过滤再连表一样的.因为left join的操作,无论从表有没有匹配的记录,它都不影响基表的行的值.但是当你反着写一下,就不一样了.declare @a table(id int,v varchar(10)) insert @a select 1,'a' union all select 2,'b'declare @b table(id int,v varchar(10)) insert @b select 1,'a'select * from @a a left join @b b on a.id=b.id where a.v like 'a%' select * from (select * from @a where v like 'a%') a left join @b b on a.id=b.id select * from @a a left join @b b on a.id=b.id where b.v like 'a%' select * from @a a left join (select * from @b where v like 'a%') b on a.id=b.id看后面这两句的查询计划比对,就知道了.当b为从表时,先连表再 where b... 因为它是从表,那么产生行集的对应的b.v值,可能与原表不一样.而写在子查询里先过滤, 这时还是操作的b表原来的行.
--guan zhu yi xia!
insert @a select 1,'a'
union all select 2,'b'declare @b table(id int,v varchar(10))
insert @b select 1,'a'select * from @a a left join @b b on a.id=b.id where a.v like 'a%'
select * from (select * from @a where v like 'a%') a left join @b b on a.id=b.id
select * from @a a left join @b b on a.id=b.id where b.v like 'a%'
select * from @a a left join (select * from @b where v like 'a%') b on a.id=b.id看后面这两句的查询计划比对,就知道了.当b为从表时,先连表再 where b...
因为它是从表,那么产生行集的对应的b.v值,可能与原表不一样.而写在子查询里先过滤, 这时还是操作的b表原来的行.