`
jipengyun2008
  • 浏览: 33022 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

sql JOIN ON VS WHERE

    博客分类:
  • sql
 
阅读更多
问题
现有表EMP和DEPT如下:

EMP 
EMPID  EMPNAME DEPTID
1   张三     1
2   李四     2
3   王五     2
4   赵六     2
5   孙七     3


DEPT 
DEPTID  DEPTNAME
1     开发
2     测试
3     需求
4     销售


现在要看开发部门的人员情况。

这个问题只需以EMP.DEPTID等于DEPT.DEPTID为连接条件来连接两张表。一般来说,跨表查询有两种实现方法:ANSI SQL和dialect SQL



方法1

ANSI SQL,使用JOIN…ON…子句。SQL statement如下:

SELECT EMP.* FROM EMP

JOIN DEPT

ON EMP.DEPTID = DEPT.DEPTID

WHERE DEPT.DEPTID = 1



方法2

Dialect SQL,把连接条件和过滤条件都放在WHERE子句里。SQL statement如下:

SELECT EMP.* FROM EMP, DEPT

WHERE EMP.DEPTID = DEPT.DEPTID AND DEPT.DEPTID = 1



这两种方法本身都没有问题。观察这两个SQL语句可见,二者的区别在于前者把连接条件和过滤条件分开了,而后者没有分开。那么问题就来了,连接条件和过滤条件需要分开吗?在ANSI写法下,如果不分开会怎么样?例如下面的SQL statement:



方法3

SELECT EMP.* FROM EMP

JOIN DEPT

ON EMP.DEPTID = DEPT.DEPTID AND DEPT.DEPTID = 1



虽然“DEPT.DEPTID = 1”并不是连接条件,但是这里把它放到ON子句里,也能得到正确的结果。那么WHERE和ON到底有何不同呢?

分析
我上网查了一些资料,自己也做了一些试验。目前得到的结论为,对于内连接(inner join),二者并无不同(至少从结果上看,至于效率就不清楚了)。所以上面的例子中,这三种写法都OK。当然,把过滤条件放在ON子句里,可读性会差很多。

对于外连接,二者还是确有不同的。比如,我要得到某个部门(如开发)的人数,由于有的部门可能没有员工,所以这里必须用外连接。SQL statement如下:



方法一

SELECT DEPT.DEPTID, DEPT.DEPTNAME, COUNT(EMP.EMPID) AS EMPNUMBER

FROM DEPT

LEFT JOIN EMP

ON EMP.DEPTID=DEPT.DEPTID

WHERE DEPTNAME = '开发'

GROUP BY DEPT.DEPTID, DEPT.DEPTNAME



结果如下:

DEPTID  DEPTNAME EMPNUMBER
1       开发       1




这里连接条件和过滤条件就不能混用,如果把过滤条件也放到连接条件里,SQL statement如下:

方法二

SELECT DEPT.DEPTID, DEPT.DEPTNAME, COUNT(EMP.EMPID) AS EMPNUMBER

FROM DEPT

LEFT JOIN EMP

ON EMP.DEPTID=DEPT.DEPTID AND DEPTNAME = '开发'

GROUP BY DEPT.DEPTID, DEPT.DEPTNAME



方法二的实际结果跟预期结果有所不同,如下:

DEPTID  DEPTNAME  EMPNUMBER
1       开发        1
2       测试        0
3       需求        0
4       销售        0




要了解为何两个SQL语句的结果不同,就要明白SQL执行的顺序。如下:

1)       用笛卡尔乘积连接两张表;

2)       用ON条件过滤结果集;

3)       LEFT、RIGHT、FULL条件起作用;

4)       WHERE条件过滤结果集;

5)       GROUP BY起作用。

下面分别列出两种方法中每一步执行的结果。

方法一
1)    用笛卡尔乘积连接两张表;

DEPTID  DEPTNAME  EMPID  EMPNAME  DEPTID
1          开发    1      张三    1
1          开发    2      李四    2
1          开发    3      王五    2
1          开发    4      赵六    2
1          开发    5      孙七    3
2          测试    1      张三    1
2          测试    2      李四    2
2          测试    3      王五    2
2          测试    4      赵六    2
2          测试    5      孙七    3
3          需求    1      张三    1
3          需求    2      李四    2
3          需求    3      王五    2
3          需求    4      赵六    2
3          需求    5      孙七    3
4          销售    1      张三    1
4          销售    2      李四    2
4          销售    3      王五    2
4          销售    4      赵六    2
4          销售    5      孙七    3

2)    用ON条件过滤结果集;

DEPTID    DEPTNAME   EMPID  EMPNAME  DEPTID
1            开发    1        张三    1
2            测试    2        李四    2
3            需求    5        孙七    3

3)    LEFT、RIGHT、FULL条件起作用;

DEPTID    DEPTNAME    EMPID    EMPNAME    DEPTID
1           开发       1         张三    1
2           测试       2         李四    2
3           需求       5         孙七    3
4           销售      NULL       NULL    NULL

4)    WHERE条件过滤结果集;

DEPTID    DEPTNAME  EMPID    EMPNAME    DEPTID
1            开发    1         张三    1

5)    GROUP BY起作用。

DEPTID    DEPTNAME    EMPNUMBER
1          开发         1

方法二
1)    用笛卡尔乘积连接两张表;同方法一
2)    用ON条件过滤结果集;

DEPTID  DEPTNAME  EMPID  EMPNAME  DEPTID
1          开发    1      张三    1

3)    LEFT、RIGHT、FULL条件起作用;

DEPTID  DEPTNAME  EMPID  EMPNAME  DEPTID
1         开发    1       张三    1
2         测试    NULL    NULL    NULL
3         需求    NULL    NULL    NULL
4         销售    NULL    NULL    NULL

4)    WHERE条件过滤结果集;无WHERE过滤条件
5)    GROUP BY起作用。

DEPTID  DEPTNAME  EMPNUMBER
1          开发    1
2          测试    0
3          需求    0
4          销售    0

结论
对于外连接,一定注意不要把连接条件和过滤条件混淆了。其实,即使对于内连接,把连接条件和过滤条件分开来,对于可读性而言也很有好处。总而言之,推荐大家在跨表查询时,使用标准SQL写法(JOIN…ON…),并且把连接条件和过滤条件严格分开来。

分享到:
评论

相关推荐

    left_join_on_and与left_join_on_where的区别

    left_join_on_and与left_join_on_where的区别

    sql语句join中on和where的区别

    ### SQL语句JOIN中ON和WHERE的区别 #### 引言 在SQL中,JOIN操作用于合并两个或多个表中的行。正确理解`ON`和`WHERE`子句的区别对于高效地编写查询至关重要。本文将详细解释这两者的不同,并通过具体的例子来加深...

    SQL _join on 和where的执行顺序1

    对于LEFT JOIN,WHERE条件的过滤发生在最后,不满足条件的记录会被删除,但对于INNER JOIN,ON和WHERE的效果相同,因为它们都只会保留匹配的记录。 举例说明,假设我们有两个表: 表1(tab1): | tab1.id | tab1....

    join on 语句及扩展

    这里我们将深入探讨几种JOIN类型及其使用,以及ON和WHERE子句的区别。 1. INNER JOIN: INNER JOIN返回两个表中匹配的记录。这意味着如果某个记录在其中一个表中没有对应的匹配项,那么这个记录就不会出现在结果集中...

    sql中的left join及on、where条件关键字的区别详解

    在SQL查询中,JOIN操作是连接两个或多个表格的关键字,用于从多个表格中合并数据。LEFT JOIN(在某些数据库中称为LEFT OUTER JOIN)是一种特殊的JOIN类型,它着重于从左表(即指定的第一个表格)返回所有行,即使在...

    sql join on 用法

    1. SELECT * FROM a LEFT JOIN b ON a.id = b.id WHERE a.id = 1 2. SELECT * FROM a LEFT JOIN b ON a.id = b.id AND a.id = 1 3. SELECT * FROM a LEFT JOIN b ON a.id = b.id AND b.id = 1 4. SELECT * FROM a ...

    PL/SQL Join实例分析

    在PL/SQL(Oracle数据库的编程语言)中,JOIN语法尤其重要,因为它是处理复杂查询的基础。以下是PL/SQL中不同类型的JOIN及其特点的详细分析: 1. **左连接(LEFT JOIN)**: 左连接返回左表(Aa)的所有行,即使在...

    SQL中JOIN的使用详解

    ### SQL中JOIN的使用详解 在SQL查询语言中,`JOIN`操作是非常重要的一个部分,它主要用于合并两个或多个表中的数据。通过不同的`JOIN`类型,我们可以灵活地获取所需的组合数据。本文将详细介绍五种主要的`JOIN`类型...

    解析sql语句中left_join、inner_join中的on与where的区别

    同样,在SQL语句6和7中,虽然使用了不同的语法(WHERE子句代替ON子句),但由于INNER JOIN的特性,它们产生的结果也是相同的,因为所有条件都在寻找匹配记录时被考虑。 WHERE子句通常用于过滤已经JOIN后的结果,而...

    【SQL】在sql server中 delete时 使用INNER JOIN

    ### SQL Server 中 DELETE 语句结合 INNER JOIN 的应用 #### 背景介绍 在数据库管理与维护过程中,经常会遇到需要删除表中的某些记录的情况。简单地使用 `DELETE` 语句可以删除单个表中的数据,但在多表关联的情况...

    sql查询左连接on与where的区别(2).pdf

    而on和where是用于指定连接条件和过滤结果集的关键字,在Left Join中它们的使用方法和时机对最终查询结果会产生重大影响。 在Left Join的语句中,on关键字用于指定连接条件,它定义了两张表之间如何关联,确保了...

    深入Oracle的left join中on和where的区别详解

    当我们涉及到LEFT JOIN时,可能会遇到使用ON和WHERE子句的情况,两者虽然都可以用来指定条件,但在语义上有所区别。 首先,ON子句是在生成联接结果集(临时表)时应用的条件。无论ON条件是否为真,都会返回左表的...

    画图解释 SQL join 语句1

    SQL Join 语句详解 SQL Join 语句是数据库管理系统中最基本也是最重要的语句之一。它允许用户从多个表中检索数据,并将其组合成一个结果集。今天,我们将使用图形来解释 SQL Join 语句的各种类型。 INNER JOIN ...

    sql语句中join的用法

    ### SQL语句中JOIN的用法详解 在SQL查询语言中,`JOIN`是一个非常重要的概念,它允许我们从两个或多个表中提取数据。通过使用不同类型的JOIN操作,我们可以根据表之间的关系来灵活地组织数据。下面我们将详细介绍几...

    LINQ to SQL语句之Join和Order By

    [t0].[Discontinued] FROM [dbo].[Products] AS [t0] LEFT OUTER JOIN [dbo].[Suppliers] AS [t1] ON [t1].[SupplierID] = [t0].[SupplierID] WHERE ([t1].[Country] = @p0) AND ([t0].[UnitsInStock] = @p1) -- @p0...

    SQL中的left outer join,inner join,right outer join用法详解

    SELECT * FROM t_institution i RIGHT OUTER JOIN t_teller t ON i.inst_no = t.inst_no WHERE i.inst_no = "5801" 全外连接(Full Outer Join) 全外连接是将左、右两个表的全部行连接起来,例如: SELECT * ...

    SQL 之JOIN 用法完全版.rar

    JOIN操作通常与ON子句一起使用来指定连接条件,而WHERE子句则用于过滤结果集。需要注意的是,ON条件和WHERE条件的区别:ON用于定义表之间的关联,而WHERE用于筛选满足特定条件的行。 8. **多表JOIN**: SQL允许...

    解析mysql left( right ) join使用on与where筛选的差异

    在使用LEFT JOIN和RIGHT JOIN时,条件筛选可以使用ON和WHERE子句。它们之间的差异是很多人容易混淆的地方。ON子句是在连接操作中对连接条件进行指定,而WHERE子句通常用于对结果集进行过滤。由于这两者在查询的逻辑...

    sql的left join和count应用

    在SQL语言中,`LEFT JOIN` 和 `COUNT` 是两种非常重要的操作,它们在数据库查询中扮演着关键角色。在这个问题中,我们看到一个数据表 `TPL_WORD1`,它包含字段 `Wordid`(主键)、`idFuid`(上一级节点ID)和 `Name`...

Global site tag (gtag.js) - Google Analytics