日期:2014-05-17  浏览次数:20693 次

好奇葩的问题(leftjoin)


select distinct gx.GXMXID,LStationID,gx.GXID1 as GXID,gx.ZhuanYeID,LeiXingID1 as LeiXingID,LeiXingMingChen1 as LeiXingMingChen,GXWCShiJian as TopTime,
(dbo.f_JianLianCompleteInfo('KDDG00001890',LeiXingID1,104)) as IsFinish
FROM #tmp gx left join SF_GXShangChuan a on gx.GXMXID=a.GXMXSID and  (LStationID is null or LStationID = 'KDDG00001890')
where TomComID1 is  null and gx.ZhuanYeID=104 --and (LStationID is null or LStationID = 'KDDG00001890')

select distinct LStationID,gx.GXID1 as GXID,gx.ZhuanYeID,LeiXingID1 as LeiXingID,LeiXingMingChen1 as LeiXingMingChen,GXWCShiJian as TopTime,
(case when GXWCShiJian is not null and FinishContent=3 then 1 else 0 end) as IsFinish
FROM #tmp gx left join SF_GXShangChuan a on gx. GXMXID=a.GXMXSID 
where TomComID1 is  null and gx.ZhuanYeID=104 and  (LStationID is null or LStationID = 'KDDG00001890')

这两个sql语句竟然查询的结果集不一样,第一条是 left join 第二条变成 innerjoin 啦。
相当无语。

------解决方案--------------------
优化器会根据实际语句优化,我见过一个例子,3个表关联,当你需要查两个表的数据时,执行计划会关联3表,但是把select中的列限制到一个表的列时,它就把其中一个表去掉,实际上之关联两个表
------解决方案--------------------
这样的2条语句的查询肯定是不一样的。
------解决方案--------------------
为什么会不一样呢。

虽然看着都是left join ,

但是:

1.left join 把(LStationID is null or LStationID = 'KDDG00001890')条件写到了on条件后。

2.left join中把(LStationID is null or LStationID = 'KDDG00001890')写到了where后面,这样sql server就会自动把left join 转化为inner join。

也就是这样:

--这个还是left join
select *
from a 
left join b
       on a.id = b.id and b.xxx = 'xxx'


--这个就是转化为inner join
select *
from a 
left join b
       on a.id = b.id 
where b.xxx = 'xxx'

------解决方案--------------------
所以,如果你是left  join 那么最好是把关联条件写到 on后面,因为写到where 后面,其实从语义的角度,就已经转化为inner join了,因为这样也是一样的:

select *
from a
inner join b
        on a.id = b.id

等价于:

select *
from a,b
w