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的区别分析的更多相关文章

  1. sql语句中left join、right join 以及inner join之间的使用与区别

    sql语句中left join.right join 以及innerjoin之间的使用与区别 left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录  right join( ...

  2. sql中in和exist语句的区别?(补充了left join和right join)

    in和exists(摘录自百度)in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询. 如果两个表中一个较小,一个是大表,则子查询表大的用exi ...

  3. sql语句中left join和inner join中的on与where的区别分析

    关于SQL SERVER的表联接查询INNER JOIN .LEFT JOIN和RIGHT JOIN,经常会用到ON和WHERE的条件查询,以前用的时候有时是凭感觉的,总是没有搞清楚,今日亲自测试了下 ...

  4. SQL语句中LEFT JOIN、JOIN、INNER JOIN、RIGHT JOIN的区别?

    w3school的一套sql教程: http://www.w3school.com.cn/sql/index.asp left join :左连接,返回左表中所有的记录以及右表中连接字段相等的记录.r ...

  5. Hive 中Join的专题---Join详解

    1.什么是等值连接? 2.hive转换多表join时,如果每个表在join字句中,使用的都是同一个列,该如何处理? 3.LEFT,RIGHT,FULL OUTER连接的作用是什么? 4.LEFT或RI ...

  6. HIVE中join、semi join、outer join

    补充说明 left outer join where is not null与left semi join的联系与区别:两者均可实现exists in操作,不同的是,前者允许右表的字段在select或 ...

  7. Mysql中eft join、right join、inner join的区别

    left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录inner join(等值连接) 只 ...

  8. mysql中left join ,right join 以及inner join 比较

    下面是例子分析表A记录如下: aID        aNum 1           a20050111 2           a20050112 3           a20050113 4   ...

  9. Access SQL中Left Join、Right Join和Inner Join的使用

    1.表结构 表A                                     表B 2.Left Join 示例:2.1 Select * From A left join B on A. ...

随机推荐

  1. 关于Spring Cloud的核心特性

    SOA和微服务的区别 其实服务化架构已经可以解决大部分企业的需求了,那么我们为什么要研究微服务呢?先说说它们的区别: 微服务架构强调业务系统需要彻底的组件化和服务化,一个组件就是一个产品,可以独立对外 ...

  2. 教你一招用 IDE 编程提升效率的骚操作!

    阅读本文大概需要 3 分钟. IDEA 有个很牛逼的功能,那就是后缀补全(不是自动补全),很多人竟然不知道这个操作,还在手动敲代码. 这个功能可以使用代码补全来模板式地补全语句,如遍历循环语句(for ...

  3. Python学习笔记【第九篇】:Python面向对象基础

    Python语言中一切皆对象(类.属性.方法.........) 概念 面向对象编程:Object Oriented Programming 简称OOP 面向对象程序设计 面向对象和面向过程都是解决问 ...

  4. 在Ubuntu 18.04中安装pyenv(Python多版本管理工具)

    最近正在重头梳理Python的基础知识,为了更好地使用Python进行开发,防止发生版本混乱(不同的第三方库有可能因为Python版本不兼容而报错),所以需要使用pyenv进行版本管理. *** 通常 ...

  5. Emmet/Zen Coding 快速入门说明

    快速参考 以下是支持的特性: ele creates an HTML element tag 展开一个HTML元素标签 # creates an id attribute 作用于元素标签,展开一个id ...

  6. Python档案袋(变量与流程控制)

    变量与运算 得到数据类型: ii=100 print(type(ii)) #输出:<class 'int'> 强制转换: ii=100 iix=str(ii) #可为int str flo ...

  7. 解决关于 vue项目中 点击按钮路由多了个问号

    问题描述: 在vue项目开发过程中,点击按钮结果页面刷新了一遍 后来发现路径变成了 localhost:8080/?#/login 原因: 这里是 form 表单,点击了button 按钮,触发了他的 ...

  8. .Net 并发写入文件的多种方式

    1.简介 本文主要演示日常开发中利用多线程写入文件存在的问题,以及解决方案,本文使用最常用的日志案例! 2.使用File.AppendAllText写入日志 这是种常规的做法,通过File定位到日志文 ...

  9. AndroidStudio意外崩溃,电脑重启,导致重启打开Androidstudio后所有的import都出错

    解决方案: File -> Invalidate Cashes / Restart 重新编译的时候可能会碰到下面的问题: 解决方案: 关闭Android Studio,删掉工程下的.gradle ...

  10. CentOS安装使用.netcore极简教程(免费提供学习服务器)

    本文目标是指引从未使用过Linux的.Neter,如何在CentOS7上安装.Net Core环境,以及部署.Net Core应用. 仅针对CentOS,其它Linux系统类似,命令环节稍加调整: 需 ...