【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 于 -- :: 加贴在 数据库探讨: 为了建立交互站点,你需要使用数据库来存储来自访问者的信息.例如,你要建立一个职业介绍服务的站点,你就需要存储诸如个人简 ...
随机推荐
- 表单Content-Type为multipart/form-data时,后台数据的接收
我们在写form提交表单的时候,后台大多数用request.getParameter的方式来接收前台输入的数据.但如果我们表单中提交的数据包含file文件传输的话,我们需要将Content-Type改 ...
- sql server management studio 连接时指定非默认端口 ,port
- pve_ceph问题汇总
在同一个网络内,建立了两个同名的群集 Jun 24 11:56:08 cu-pve05 kyc_zabbix_ceph[2419970]: ]} Jun 24 11:56:08 cu-pve05 co ...
- osg fbx 模型树结构
void Test::printOsgGroup(osg::ref_ptr<osg::Group> &groupParam) { qDebug() <<groupPar ...
- 28 Flutter 轮播图 flutter_swiper
中文地址: https://github.com/best-flutter/flutter_swiper/blob/master/README-ZH.md 基本参数 参数 默认值 描述 scrollD ...
- 利用python批量修改word文件名的方法示例
利用python批量修改word文件名的方法示例 最近不小心把硬盘给格式化了,由于当时的文件没有备份,所以一下所有的文件都没有了,于是只能采取补救措施,用文件恢复软件恢复了一部分的数据出来,但是恢复完 ...
- C#反射回顾笔记
一 .反射概述 反射提供描述程序集.模块和类型的对象(Type 类型). 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后调用其方法或访问其字段和属性. 如果代码中 ...
- rdd的元素打印
在集群上运行spark程序时,rdd的操作都在worker机上,因此输出rdd的元素将在worker机的标准输出上进行,驱动节点上不会运行,故直接才程序中写如下代码 rdd.foreach(print ...
- Node.js使用ftp连接远程ftp服务器枚举和下载文件示例
示例代码: var Ftp = require('ftp'); var fs = require('fs'); var path = require('path'); // 首先判断参数中是否包含{d ...
- swift ClassNameFromString 的替换方法 + 创建TableviewHelper
1. ClassNameFromString 的方法oc 可以正常使用,但是swift 不能直接使用的,下面的代码 func getAPPName() -> String?{ let nameK ...
