写了那么多年的SQL,居然发现自己写的是错的,实在是惭愧不已。还好没出什么问题。
于是,决定痛定思痛,纠正自己对SQL的错误认识。
我们有一个SQL:
SELECT sys.Netbios_Name0 as [Computer Name], sf.fileName FROM dbo.v_R_System as sys INNER JOIN dbo.v_FullCollectionMembership as fcm ON fcm.ResourceID = sys.ResourceID LEFT JOIN dbo.v_GS_SoftwareFile as sf ON sf.resourceID = sys.resourceID WHERE fcm.CollectionID = 'SMS00004' AND sf.fileName = 'outlook.exe'
目的是,在所有的v_FullCollectionMembership中,寻找CollectionID是SMS00004的电脑。
且看这些电脑是否安装了outlook.exe这个软件。
我们期望看到的数据是这样的:
Computer Name FileName COMP1 OUTLOOK.EXE COMP2 COMP3 OUTLOOK.EXE COMP4 COMP5 OUTLOOK.EXE
结果出现的数据是这样的:
Computer Name FileName COMP1 OUTLOOK.EXE COMP3 OUTLOOK.EXE COMP5 OUTLOOK.EXE
为什么变成inner join了呢??
解释:
当你使用where的时候,就表示你告诉SQL去返回满足where条件的记录。无论你是用inner join还是outer join。因此,尽管你选择了left join,而实际上会被执行计划重写成inner join。
换句话而言,就是where条件是保证最终的结果集必须满足的条件。
因此,我们得到了上面不愿意见到的结果。
那应该怎么办?改写一下:
SELECT sys.Netbios_Name0 as [Computer Name], sf.fileName FROM dbo.v_R_System as sys INNER JOIN dbo.v_FullCollectionMembership as fcm ON fcm.ResourceID = sys.ResourceID LEFT JOIN dbo.v_GS_SoftwareFile as sf ON sf.resourceID = sys.resourceID AND sf.fileName = 'outlook.exe' --<Check it out> WHERE fcm.CollectionID = 'SMS00004'
把条件写到on里面就可以了。
那是不是所有的情况,都可以用on来解决呢?不,不是的。
看下面的例子:
on的执行条件相当于if
两个record比较的时候,条件为true,则返回数据,条件为false则返回null
对于on的情况,我们可以看到,on是完全不会过滤数据的。
当使用OUTER JOIN (包括LEFT , RIGHT, FULL)
都会尽可能低保持数据的原状,因此对于一些数据量特别大的表,还是会有困扰的。
那么where条件和on条件如何选择??
在过滤数据的时候,使用where。
因为where一般会通过执行计划优化,缩小查询的范围,使得结果集足够小。
而在需要保留全面信息的时候,就要把一部分的条件,写到on里面去。
总结:
where用于缩小结果集,但是会强行进行inner join
on用于保持完整数据,但是会判断所有的数据
参考内容:
http://www.tech-recipes.com/rx/47637/inner-and-left-outer-join-with-where-clause-vs-on-clause/
http://myitforum.com/cs2/blogs/jnelson/archive/2007/11/16/108359.aspx
相关推荐
总结一下,LEFT JOIN和RIGHT JOIN的区别在于它们对缺失匹配项的处理方式:LEFT JOIN保持左表的完整性,而RIGHT JOIN保持右表的完整性。INNER JOIN则只保留两表中的交集部分。选择使用哪种JOIN取决于你的查询需求,即...
### SQL语句JOIN中ON和WHERE的区别 #### 引言 在SQL中,JOIN操作用于合并两个或多个表中的行。正确理解`ON`和`WHERE`子句的区别对于高效地编写查询至关重要。本文将详细解释这两者的不同,并通过具体的例子来加深...
left_join_on_and与left_join_on_where的区别
### SQL Server 中 DELETE 语句结合 INNER JOIN 的应用 #### 背景介绍 在数据库管理与维护过程中,经常会遇到需要删除表中的某些记录的情况。简单地使用 `DELETE` 语句可以删除单个表中的数据,但在多表关联的情况...
### inner join、left join、right join、outer join之间的区别 在数据库操作中,连接(Join)是一种非常重要的操作,用于组合两个或多个表中的数据。根据连接的方式不同,可以分为几种类型:`INNER JOIN`、`LEFT ...
在SQL查询中,JOIN操作是用于合并两个或更多表中的数据的关键部分,它允许你在不同表之间建立联系,以便从多个源获取所需的信息。这里我们将深入探讨几种JOIN类型及其使用,以及ON和WHERE子句的区别。 1. INNER ...
即使ON条件中的某些记录不满足,LEFT JOIN、RIGHT JOIN和FULL JOIN仍然会返回左表或右表的记录,只是相应的右表或左表的字段会填充为NULL。 2. WHERE条件: WHERE条件在中间表生成后应用,用于进一步筛选最终结果...
SQL 提供了多种类型的连接方式,它们之间的区别在于:从相互交叠的不同数据集合中选择用于连接的行时所采用的方法不同。 1. 内连接(Inner Join):只连接匹配的行。 2. 左外连接(Left Outer Join):包含左边表的...
### SQL中JOIN的使用详解 在SQL查询语言中,`JOIN`操作是非常重要的一个部分,它主要用于合并两个或多个表中的数据。通过不同的`JOIN`类型,我们可以灵活地获取所需的组合数据。本文将详细介绍五种主要的`JOIN`类型...
### SQL中的Join类型详解 在数据库操作中,`JOIN`是一种非常重要的操作,它用于将两个或多个表中的行合并到一起,以便于查询和分析跨表的数据。根据不同的连接方式,`JOIN`可以分为几种类型,包括`INNER JOIN`、`...
SQL Left Join、Right Join和Inner Join都是用于组合表数据的查询操作,但它们之间存在着明显的区别。 * Left Join:以左表为基础,返回左表中的所有记录和右表中符合条件的记录。 * Right Join:以右表为基础,...
总之,LEFT JOIN、RIGHT JOIN、INNER JOIN和OUTER JOIN是SQL语言中的核心部分,理解和熟练运用它们对于任何数据库开发人员都至关重要。通过不断的实践和学习,你可以更好地掌握这些JOIN类型,并在解决复杂数据查询...
在SQL语言中,`LEFT JOIN` 和 `COUNT` 是两种非常重要的操作,它们在数据库查询中扮演着关键角色。在这个问题中,我们看到一个数据表 `TPL_WORD1`,它包含字段 `Wordid`(主键)、`idFuid`(上一级节点ID)和 `Name`...
### SQL中的INNER JOIN详解 #### 一、INNER JOIN的基本概念 **INNER JOIN** 是SQL中最常用的连接类型之一,主要用于从两个或多个表中提取数据,其中仅返回那些满足连接条件的记录。简单来说,INNER JOIN返回的是两...
### SQL语句中JOIN的用法详解 在SQL查询语言中,`JOIN`是一个非常重要的概念,它允许我们从两个或多个表中提取数据。通过使用不同类型的JOIN操作,我们可以根据表之间的关系来灵活地组织数据。下面我们将详细介绍几...
选择正确的JOIN类型取决于你需要获取的数据类型以及数据表之间的关系。此外,优化JOIN操作对于提高查询性能也至关重要,比如通过使用索引、避免全表扫描和合理设计JOIN条件等方法。在PL/SQL Developer这样的开发环境...
### SQL的INNER JOIN语法 #### 一、概念与作用 在SQL语言中,`INNER JOIN`是一种连接(Join)操作,用于从两个或多个表中提取数据,仅返回那些匹配的记录。简单来说,它会查找两个表中具有共同属性(如相同的键值...
在SQL语言中,连接(Join)操作是一种非常重要的数据整合方式,主要用于从两个或多个表中提取数据。根据连接方式的不同,可以分为多种类型,包括内连接(Inner Join)、左连接(Left Join)以及右连接(Right Join)...
在SQL(结构化查询语言)中,JOIN操作是用于合并两个或多个表的数据,以便根据它们之间的关联性创建新的结果集。JOIN关键字是SQL查询中的关键部分,它允许我们在不同的表之间建立联系,以获取更丰富的信息。在这个...
LINQ to SQL语句之Join和Order By部分代码 语句描述:这个例子在From子句中使用外键导航筛选在西雅图的雇员,同时列出其所在地区。这条生成SQL语句为: SELECT [t0].[FirstName], [t0].[LastName], [t2]....