Transact-SQLSQL Server自动把left join自动转化为inner join以及关联时的数据重复问题
Posted lonelyxmas
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Transact-SQLSQL Server自动把left join自动转化为inner join以及关联时的数据重复问题相关的知识,希望对你有一定的参考价值。
原文:【Transact-SQL】SQL Server自动把left join自动转化为inner join、以及关联时的数据重复问题
1、SQL Server自动把left join自动转化为inner join的问题:
下面的两个语句都是left join的,但是一个却转化成了 inner join
- drop table a,B
- go
-
- create table a(id int)
-
- insert into a
- select 1 union all
- select 2
-
- create table b(id int,xxx varchar(10))
-
- insert into b
- select 1,‘xxx‘ union all
- select 2,‘xx‘
- go
-
-
- --这个还是left join
- select *
- from a
- left join b
- on a.id = b.id and b.xxx = ‘xxx‘
- /*
- id id xxx
- 1 1 xxx
- 2 NULL NULL
- */
-
-
- select * --这个就是转化为inner join
- from a
- left join b
- on a.id = b.id
- where b.xxx = ‘xxx‘
- /*
- id id xxx
- 1 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并按照需求进行聚合计算,然后再进行关联,这样就不会导致数字偏大。
以上是关于Transact-SQLSQL Server自动把left join自动转化为inner join以及关联时的数据重复问题的主要内容,如果未能解决你的问题,请参考以下文章