【Transact-SQL】SQL 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-SQL】SQL Server自动把left join自动转化为inner join、以及关联时的数据重复问题的更多相关文章
- 浅谈SQL Server中的三种物理连接操作(Nested Loop Join、Merge Join、Hash Join)
简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...
- Sql Server中查询今天、昨天、本周、上周、本月、上月数据
Sql Server中查询今天.昨天.本周.上周.本月.上月数据 在做Sql Server开发的时候有时需要获取表中今天.昨天.本周.上周.本月.上月等数据,这时候就需要使用DATEDIFF()函数及 ...
- VS2010在网络共享目录使用IntelliSense、ipch、sdf和SQL Compact Server相关问题
Microsoft SQL Compact Server 是专用于 Visual Studio 的单机SQL 数据库.数据库文件名的后缀为SDF. 而VS2010 拒绝在网络共享目录中建立和打开SDF ...
- SQL Server的唯一键和唯一索引会将空值(NULL)也算作重复值
我们先在SQL Server数据库中,建立一张Students表: CREATE TABLE [dbo].[Students]( ,) NOT NULL, ) NULL, ) NULL, [Age] ...
- [SQL]SQL语言入门级教材_跟我学SQL(六)
跟我学SQL:(一)数据查询 且不说你是否正在从事编程方面的工作或者不打算学习SQL,可事实上几乎每一位开发者最终都会遭遇它.你多半还用不着负责创建和维持某个,但你怎么着也该知道以下的一些有关的SQL ...
- [SQL] SQL 基础知识梳理(四) - 数据更新
SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 序 这是<SQL 基础知识梳理( ...
- 在MyBatis中查询数据、涉及多参数的数据访问操作、插入数据时获取数据自增长的id、关联表查询操作、动态SQL、关于配置MyBatis映射没有代码提示的解决方案
1. 单元测试 在单元测试中,每个测试方法都需要执行相同的前置代码和后置代码,则可以自定义2个方法,分别在这2个方法中执行前置代码和后置代码,并为这2个方法添加@Before和@After注解,然后, ...
- [SQL] SQL 基础知识梳理(五) - 复杂查询
SQL 基础知识梳理(五) - 复杂查询 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5939796.html 序 这是<SQL 基础知识梳理( ...
- [SQL]SQL语言入门级教材_SQL数据操作基础(二)
SQL数据操作基础(初级) netnova 于 -- :: 加贴在 数据库探讨: 为了建立交互站点,你需要使用数据库来存储来自访问者的信息.例如,你要建立一个职业介绍服务的站点,你就需要存储诸如个人简 ...
随机推荐
- DELPHI搭建centos开发环境
DELPHI搭建centos7开发环境 关闭防火墙 搭建开发环境,还是直接关闭LINUX防火墙,省事. 否则,使用到的网络端口号,都要在防火墙开放,麻烦. systemctl disable fire ...
- git sub module
https://github.com/ViRb3/de4dot-cex/blob/master/.gitmodules git submodule sync command - what is it ...
- HashSet的实现原理,简单易懂
HashSet的实现原理,简单易懂 答: HashSet实际上是一个HashMap实例,都是一个存放链表的数组.它不保证存储元素的迭代顺序:此类允许使用null元素.HashSet中不允许有重复元 ...
- LeetCode_119. Pascal's Triangle II
119. Pascal's Triangle II Easy Given a non-negative index k where k ≤ 33, return the kth index row o ...
- iOS-条形码扫描技术SDK:ZBar(转)
ios条形码扫描技术 iOS 应用里实现条形码扫描功能,有个免费开源的 SDK:ZBar(http://zbar.sourceforge.net/iphone/sdkdoc/install.html) ...
- C#RSA加密解密(对接PHP)
上篇文章中写的RSA加密是针对C#的,现在外部调用的是PHP,我们平常见到的RSA无论公钥和私钥都是一长串数字,很显然C#生成的XML不是通用的加密.如果外部调用需要处理一下. 一.首先可以去网上找一 ...
- VMware15安装Centos7超详细过程
本篇文章主要介绍了VMware安装Centos7超详细过程(图文),具有一定的参考价值,感兴趣的小伙伴们可以参考一下 1.软硬件准备 软件:推荐使用VMwear15,我用的是VMwear 15 镜像: ...
- TCP Socket + UDP Socket
小例子:http://soft.yesky.com/238/2035738.shtml 服务器程序: #include <iostream> #include <WinSock2.h ...
- Android核心程序之SystemUI - (一)开篇
UI是实现用户交互的重要途径之一,而Android中一个重要的UI元素就是SystemUI,本文分析基于Android 5.1,分析SystemUI的启动及运行过程. SystemUI源代码所在路径为 ...
- java枚举的线程安全及序列化
原文链接:https://www.cnblogs.com/z00377750/p/9177097.html https://www.cnblogs.com/chiclee/p/9097772.html ...