ql语句中left join和inner join中的on与where的区别分析
sql语句中left join和inner join中的on与where的区别分析
关于SQL SERVER的表联接查询INNER JOIN 、LEFT JOIN和RIGHT JOIN,经常会用到ON和WHERE的条件查询,以前用的时候有时是凭感觉的,总是没有搞清楚,今日亲自测试了下,理解到了一些内容,在此分享。
要测试,首先我们来创建三张表,数据库就根据自己的情况而定
创建表TestJoinOnOrWhere_A、TestJoinOnOrWhere_B、TestJoinOnOrWhere_C

/****** Object: Table [dbo].[TestJoinOnOrWhere_A] Script Date: 2015/4/3 14:34:41 ******/
CREATE TABLE [dbo].[TestJoinOnOrWhere_A](
[id] [int] NULL,
[value] [int] NULL
) ON [PRIMARY] GO
/****** Object: Table [dbo].[TestJoinOnOrWhere_B] Script Date: 2015/4/3 14:34:41 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[TestJoinOnOrWhere_B](
[id] [int] NULL,
[value] [int] NULL
) ON [PRIMARY] GO
/****** Object: Table [dbo].[TestJoinOnOrWhere_C] Script Date: 2015/4/3 14:34:41 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[TestJoinOnOrWhere_C](
[id] [int] NULL,
[value] [int] NULL
) ON [PRIMARY]

表创建好了然后我们添加几条数据

INSERT [dbo].[TestJoinOnOrWhere_A] ([id], [value]) VALUES (1, 1)
INSERT [dbo].[TestJoinOnOrWhere_A] ([id], [value]) VALUES (2, 1)
INSERT [dbo].[TestJoinOnOrWhere_A] ([id], [value]) VALUES (3, 2)
INSERT [dbo].[TestJoinOnOrWhere_B] ([id], [value]) VALUES (1, 1)
INSERT [dbo].[TestJoinOnOrWhere_B] ([id], [value]) VALUES (2, 3)
INSERT [dbo].[TestJoinOnOrWhere_B] ([id], [value]) VALUES (3, 4)
INSERT [dbo].[TestJoinOnOrWhere_C] ([id], [value]) VALUES (1, 1)
INSERT [dbo].[TestJoinOnOrWhere_C] ([id], [value]) VALUES (2, 2)
INSERT [dbo].[TestJoinOnOrWhere_C] ([id], [value]) VALUES (3, 3)

现在我们开始测试
语句1:SELECT * FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND a.value = 1
语句2:SELECT * FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id
结果1:
id value id value
-------------------------------
1 1 1 1
2 1 2 3
3 2 NULL NULL
结果2
id value id value
-------------------------------
1 1 1 1
2 1 2 3
3 2 3 4
在网上查询到,有的人说a.value = 1没有生效,其实不然,它已经生效,只是在左联接查询时,左表的数据是不会受影响,只有右表的数据会根据a.value = 1条件取出左表(a表)Value为1的行,通过上面两个语句的结果就可以看出,那么我们用右表筛选条件会出现什么呢?看看下面语句
语句3:SELECT * FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND b.value = 1
结果3:
id value id value
-------------------------------
1 1 1 1
2 1 NULL NULL
3 2 NULL NULL
以上结果看出,也只是影响了右表的数据
语句4:SELECT * FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.value = 1
结果4:
id value id value
-------------------------------
1 1 1 1
1 1 2 3
1 1 3 4
2 1 1 1
2 1 2 3
2 1 3 4
3 2 NULL NULL
从上面语句结果看出,也只影响了右表的数据(取出所有a表value对应为1的b表数据)
所以在左联接查询时ON后面的条件只会影响右表,相反右联接查询影响的就是左边的表数据
如果用WHERE呢?我们看下下面的语句
语句5:SELECT * FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id where a.value = 1 语句6:SELECT * FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id where b.value = 1
结果5:
id value id value
-------------------------------
1 1 1 1
2 1 2 3
结果6:
id value id value
-------------------------------
1 1 1 1
可以从结果看出,这个影响的结果就是全部的表,就相当于通过ON条件联接查询查询的结果,然后通过WHERE后面的条件取总体筛选
对于INNER JOIN 的ON条件会怎样影响呢?先看下面语句执行结果
语句7: SELECT * FROM dbo.TestJoinOnOrWhere_A AS a INNER JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND a.value = 1
语句8: SELECT * FROM dbo.TestJoinOnOrWhere_A AS a INNER JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND b.value = 1
语句9: SELECT * FROM dbo.TestJoinOnOrWhere_A AS a INNER JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id WHERE a.value = 1
语句10:SELECT * FROM dbo.TestJoinOnOrWhere_A AS a INNER JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id WHERE b.value = 1
结果7/9:
id value id value
-------------------------------
1 1 1 1
2 1 2 3
结果8/10:
id value id value
-------------------------------
1 1 1 1
上面通过WHERE和ON查询出来的结果是一样的,由此可看出,INNER JOIN 的ON条件和WHERE条件影响的都是一个效果,影响整体的查询结果。
下面我们再来看下对于LEFT JOIN的三表查询对于WHERE和ON影响的结果
语句11:SELECT a.id AS a_id,a.value AS a_value,b.id AS b_id,b.value AS b_value,c.id AS c_id,c.value AS c_value FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND a.value = 1 LEFT JOIN dbo.TestJoinOnOrWhere_C AS c ON b.id = c.id
语句12:SELECT a.id AS a_id,a.value AS a_value,b.id AS b_id,b.value AS b_value,c.id AS c_id,c.value AS c_value FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND b.value = 1 LEFT JOIN dbo.TestJoinOnOrWhere_C AS c ON b.id = c.id
语句13:SELECT a.id AS a_id,a.value AS a_value,b.id AS b_id,b.value AS b_value,c.id AS c_id,c.value AS c_value FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND a.value = 1 LEFT JOIN dbo.TestJoinOnOrWhere_C AS c ON b.id = c.id AND b.value = 1
语句14:SELECT a.id AS a_id,a.value AS a_value,b.id AS b_id,b.value AS b_value,c.id AS c_id,c.value AS c_value FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND a.value = 1 LEFT JOIN dbo.TestJoinOnOrWhere_C AS c ON b.id = c.id AND c.value = 2
结果11:
a_id a_value b_id b_value c_id c_value
-----------------------------------------------------
1 1 1 1 1 1
2 1 2 3 2 2
3 2 NULL NULL NULL NULL
结果12:
a_id a_value b_id b_value c_id c_value
-----------------------------------------------------
1 1 1 1 1 1
2 1 NULL NULL NULL NULL
3 2 NULL NULL NULL NULL
结果13:
a_id a_value b_id b_value c_id c_value
-----------------------------------------------------
1 1 1 1 1 1
2 1 2 3 NULL NULL
3 2 NULL NULL NULL NULL
结果14:
a_id a_value b_id b_value c_id c_value
-----------------------------------------------------
1 1 1 1 NULL NULL
2 1 2 3 2 2
3 2 NULL NULL NULL NULL
通过以上三表数据查询结果,可以看出,LEFT JOIN 查询,对于ON的单独表条件始终只会影响条件表的右表(如,a.value=1会影响b表关联的a表value字段值为1的行,并不会限制a表的数据只显示value=1的行),RIGHT JOIN 影响效果恰恰相反
在使用ON条件时LEFT JOIN影响的是右侧的第二张第三张表,并不会对最左侧的表影响,所以对于a,b,c,三张表,a表数据是不受ON条件影响的,只会影响联接查询后的b或c数据
而WHERE就相当于在WHERE条件之前查询的数据当着一个表,然后通过WHERE条件进行筛选数据,所以影响的是整体。
本文来自wl131710,转载请注明出处:http://www.cnblogs.com/wanglu/p/4390612.html
ql语句中left join和inner join中的on与where的区别分析的更多相关文章
- sql语句中left join、right join 以及inner join之间的使用与区别
sql语句中left join.right join 以及innerjoin之间的使用与区别 left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join( ...
- sql中in和exist语句的区别?(补充了left join和right join)
in和exists(摘录自百度)in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询. 如果两个表中一个较小,一个是大表,则子查询表大的用exi ...
- sql语句中left join和inner join中的on与where的区别分析
关于SQL SERVER的表联接查询INNER JOIN .LEFT JOIN和RIGHT JOIN,经常会用到ON和WHERE的条件查询,以前用的时候有时是凭感觉的,总是没有搞清楚,今日亲自测试了下 ...
- SQL语句中LEFT JOIN、JOIN、INNER JOIN、RIGHT JOIN的区别?
w3school的一套sql教程: http://www.w3school.com.cn/sql/index.asp left join :左连接,返回左表中所有的记录以及右表中连接字段相等的记录.r ...
- Hive 中Join的专题---Join详解
1.什么是等值连接? 2.hive转换多表join时,如果每个表在join字句中,使用的都是同一个列,该如何处理? 3.LEFT,RIGHT,FULL OUTER连接的作用是什么? 4.LEFT或RI ...
- HIVE中join、semi join、outer join
补充说明 left outer join where is not null与left semi join的联系与区别:两者均可实现exists in操作,不同的是,前者允许右表的字段在select或 ...
- Mysql中eft join、right join、inner join的区别
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录inner join(等值连接) 只 ...
- mysql中left join ,right join 以及inner join 比较
下面是例子分析表A记录如下: aID aNum 1 a20050111 2 a20050112 3 a20050113 4 ...
- Access SQL中Left Join、Right Join和Inner Join的使用
1.表结构 表A 表B 2.Left Join 示例:2.1 Select * From A left join B on A. ...
随机推荐
- 通过脚本下载GO被墙或常用的相关包
脚本描述 脚本依赖环境:Windows,GO,GIT 脚本将创建 temp 目录,并拷贝相关包到第一个 GOPATH 中 可将脚本保存到本地自行添加被墙或者常用的包 完整脚本代码 @echo off ...
- 使用Python多渠道打包apk
使用Python生成多渠道包 往apk包中追加到一个空文件到META-INF目录以标识渠道,Android中获取此文件即可获得App的下载渠道 首先在info文件夹新建一个qdb.txt的空文本文件 ...
- 从构建分布式秒杀系统聊聊WebSocket推送通知
秒杀架构到后期,我们采用了消息队列的形式实现抢购逻辑,那么之前抛出过这样一个问题:消息队列异步处理完每个用户请求后,如何通知给相应用户秒杀成功? 场景映射 首先,我们举一个生活中比较常见的例子:我们去 ...
- Windows下Tomcat内存占用过高问题跟踪(ProcessExplorer+jstack)
一.问题描述 Tomcat下面部署很多个java项目的war包,tomcat启动一段时间后,发现cpu占用过高,整个界面卡死! 二.通过process explorer查看java进程下的线程 pro ...
- SpringAop实操之记录关键业务请求数据
AOP,中文名称,切面.在不影响业务代码情况下,实现想要的功能,是个真炫酷的事. aop是个好东西,记录日志是必须的. 记录数据也一样的,那么也是可以用aop来实现的,这里借助注解一起解决问题吧. 因 ...
- iOS学习——iOS开发小知识点集合
在iOS学习和开发过程中,经常会遇到一些很小的知识点和问题,一两句话就可以解释清楚了,这样的知识点写一篇随笔又没有必要,但是又想mark一下,以备不时之需,所以就有了本文.后面遇到一些小的知识点会不断 ...
- 工欲善其事,必先利其器-Python编辑器选择(2)
前言:工欲善其事.必先利其器 一款顺手的好的编辑器可以让程序员写代码更得心应手,效率也会更高,但是编辑器本身没有好坏,只有使用者使用起来是否顺手而已,这里简单给大家介绍几款常用的可以编辑Python的 ...
- Python常用模块——目录
Python常用模块学习 Python模块和包 Python常用模块time & datetime &random 模块 Python常用模块os & sys & sh ...
- 使用maven插件构建docker镜像
为什么要用插件 主要还是自动化的考虑,如果额外使用Dockerfile进行镜像生成,可能会需要自己手动指定jar/war位置,并且打包和生成镜像间不同步,带来很多琐碎的工作. 插件选择 使用比较多的是 ...
- ASP.NET Core微服务+Tabler前端框架搭建个人博客1--开始前想说的话
写在前面 本人为在读研究生,特别喜欢.NET,觉得.NET的编程方式.语法都特别友好,学习.NET Core已经差不多有一年半了,从一开始不知道如何入门到现在终于可以编写一些小的应用程序,想一想还是非 ...