【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 于 -- :: 加贴在 数据库探讨: 为了建立交互站点,你需要使用数据库来存储来自访问者的信息.例如,你要建立一个职业介绍服务的站点,你就需要存储诸如个人简 ...
随机推荐
- VUE -- 对 Element UI table中数据进行二次处理
时间——日期 后台经常给我们返回的是 时间戳 (例如:1535620671) 这时候我们页面展现的时候需要将时间戳转换为我们要的格式 例如 (YYYY-MM-DD HH:mm:ss) 如果是在Elem ...
- 【SpringBoot/MVC】从Oracle下载百万条记录的CSV
工程下载地址:https://files.cnblogs.com/files/xiandedanteng/CsvDownloadOracle20191110-2.rar 画面: 核心代码: 控制器: ...
- 快速查看MySQL数据库的版本号
1.利用dos命令连接数据库后即有版本号信息 2.利用navicat连接mysql的客户端工具也是可以查看的 直接选中一个连接,然后右键-连接信息查看 3.利用专门的mysql命令查看 4.直接查看咱 ...
- 37 Flutter仿京东商城项目 结算页面布局
加群452892873 下载对应34课文件,运行方法,建好项目,直接替换lib目录 CheckOut.dart import 'package:flutter/material.dart'; impo ...
- (十八)JDBC优化使用(一)
一.将增删改方法合并,优化代码 第十七篇的UserPOImpl.java类代码可以进行优化,因为增删改方法用的都是同一种执行方法executeUpdate(),对十七篇的例子进行优化如下: 2.1 搭 ...
- jQuery学习三——事件
代码如下: <!DOCTYPE html> <html> <head> <title>jquery事件</title> </head& ...
- 【linux基础】Ubuntu下的终端多标签切换快捷键
method: 方法一: alt+ alt+ alt+ 方法二: ctrl + pageUp ctrl + pageDown 方法三: Edit--> Keybord Shortcuts 到这里 ...
- Spring mvc +ajax 发送邮件
1.前端页面--form表单提交,通过发送按钮的id=“send”定位DOM,触发ajax请求 <form class="form-horizontal" id=" ...
- 粒子系统与雨的效果 (DirectX11 with Windows SDK)
前言 最近在学粒子系统,看这之前的<<3D图形编程基础 基于DirectX 11 >>是基于Direct SDK的,而DXSDK微软已经很久没有更新过了并且我学的DX11是用W ...
- golang web框架 beego 学习 (五) 配置文件
app.conf: appname = gowebProject httpport = runmode = dev copyrequestbody = true [db] host= localhos ...
