【Transact-SQL】SQL Server自动把left join自动转化为inner join、以及关联时的数据重复问题

谁说胖子不能爱 提交于 2019-12-11 00:06:10
原文:【Transact-SQL】SQL Server自动把left join自动转化为inner join、以及关联时的数据重复问题

 

1、SQL Server自动把left join自动转化为inner join的问题:

 

下面的两个语句都是left join的,但是一个却转化成了 inner join

drop table a,Bgo create table a(id int) insert into aselect 1 union allselect 2 create table b(id int,xxx varchar(10)) insert into bselect 1,'xxx' union allselect 2,'xx'go  --这个还是left joinselect *from a left join b       on a.id = b.id and b.xxx = 'xxx'/*id	id	xxx1	1	xxx2	NULL	NULL*/   select * --这个就是转化为inner joinfrom a left join b       on a.id = b.id where b.xxx = 'xxx'/*id	id	xxx1	1	xxx*/

 

下面的图是执行计划:


 

2、下面的语句,运行后会出来几条记录呢? 

 

select*from (	select 1 as id)a left join(	select 1 as id	union all	select 1 )b on a.id = b.id left join (	select 1 as id	union all	select 1 )c on a.id = c.id 


 之所以会想到这个问题,是因为发现最近写的报表总是运行结果不对,数字偏大,报表的逻辑要比上面的语句复杂,但问题是一样的。

 

首先,查询结果要求出来明细数据,由于表a关联了表b,虽然表a中没有重复记录,但是表b中有重复记录,导致表a的一条记录与表b的2条记录关联时,结果集会有2条,然后再把产生的结果集再与表c关联,这时由于c表中也有重复数据,那么最后的结果集就会是4条。

看上去和笛卡尔积一样2*2 = 4,但其实是由于表b和表c都有重复记录,导致关联以后出现大量的重复数据,这个问题在写SQL语句的时候,一定要非常注意。

 

如果来解决这个问题呢?

一般可以先单独对有重复数据表进行去重,或者group by并按照需求进行聚合计算,然后再进行关联,这样就不会导致数字偏大。

发布了416 篇原创文章 · 获赞 135 · 访问量 94万+
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!