zoukankan      html  css  js  c++  java
  • 【TransactSQL】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并按照需求进行聚合计算,然后再进行关联,这样就不会导致数字偏大。

  • 相关阅读:
    [转载自 文顶顶]iOS开发UI篇—程序启动原理和UIApplication
    中专生自学Android到找到工作的前前后后
    HashCode与IEqualityComparer接口
    abp vnext使用记录之微服务
    asp.net core 外部认证多站点模式实现
    xamarin.android 绑定百度地图SDK遇到的问题
    asp.net core 之多语言国际化自定义资源文件
    asp.net core tags 扩展之 id 和 name
    asp.net 后台任务作业框架收集
    向量
  • 原文地址:https://www.cnblogs.com/momogua/p/8304584.html
Copyright © 2011-2022 走看看