• sql之left join、right join、inner join的区别


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

    ===============================================================================================

    Left Join / Right Join /inner join相关
    关于左连接和右连接总结性的一句话:
    左连接where只影向右表,右连接where只影响左表。



    Left Join
    select * from tbl1 Left Join tbl2 where tbl1.ID = tbl2.ID
    左连接后的检索结果是显示tbl1的所有数据和tbl2中满足where 条件的数据。
    简言之 Left Join影响到的是右边的表

    Right Join
    select * from tbl1 Right Join tbl2 where tbl1.ID = tbl2.ID
    检索结果是tbl2的所有数据和tbl1中满足where 条件的数据。
    简言之 Right Join影响到的是左边的表。

    inner join
    select * FROM tbl1 INNER JOIN tbl2 ON tbl1.ID = tbl2.ID
    功能和 select * from tbl1,tbl2 where tbl1.id=tbl2.id相同。

    其他相关资料

    1 .WHERE子句中使用的连接语句,在数据库语言中,被称为隐性连接。INNER JOIN……ON子句产生的连接称为显性连接。(其他JOIN参数也是显性连接)WHERE 和INNER JOIN产生的连接关系,没有本质区别,结果也一样。但是!隐性连接随着数据库语言的规范和发展,已经逐渐被淘汰,比较新的数据库语言基本上已经抛弃了隐性连接,全部采用显性连接了。

    2 .无论怎么连接,都可以用join子句,但是连接同一个表的时候,注意要定义别名,否则产生错误!
    a> inner join:理解为“有效连接”,两张表中都有的数据才会显示left join:理解为“有左显示”,比如on a.field=b.field,则显示a表中存在的全部数据及a\\b中都有的数据,A中有、B没有的数据以null显示
    b> right join:理解为“有右显示”,比如on a.field=b.field,则显示B表中存在的全部数据及a\\b中都有的数据,B中有、A没有的数据以null显示
    c> full join:理解为“全连接”,两张表中所有数据都显示,实际就是inner +(left-inner)+(right-inner)

    3 .join可以分主次表 外联接有三种类型:完全外联,左联,右联.
    完全外联包含两张表的所有记录.
    左联是以左边的表为主,右边的为辅,右联则相反

    4.一般要使得数据库查询语句性能好点遵循一下原则:
    在做表与表的连接查询时,大表在前,小表在
    不使用表别名,通过字段前缀区分不同表中的字段
    查询条件中的限制条件要写在表连接条件前
    尽量使用索引的字段做为查询条件.

    ===============================================================================================

    举例如下: 
    --------------------------------------------
    表A记录如下:
    aID     aNum
    1     a20050111
    2     a20050112
    3     a20050113
    4     a20050114
    5     a20050115

    表B记录如下:
    bID     bName
    1     2006032401
    2     2006032402
    3     2006032403
    4     2006032404
    8     2006032408

    --------------------------------------------
    1.left join
    sql语句如下: 
    select * from A
    left join B 
    on A.aID = B.bID

    结果如下:
    aID     aNum     bID     bName
    1     a20050111    1     2006032401
    2     a20050112    2     2006032402
    3     a20050113    3     2006032403
    4     a20050114    4     2006032404
    5     a20050115    NULL     NULL

    (所影响的行数为 5 行)
    结果说明:
    left join是以A表的记录为基础的,A可以看成左表,B可以看成右表,left join是以左表为准的.
    换句话说,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录(例子中为: A.aID = B.bID).
    B表记录不足的地方均为NULL.
    --------------------------------------------
    2.right join
    sql语句如下: 
    select * from A
    right join B 
    on A.aID = B.bID

    结果如下:
    aID     aNum     bID     bName
    1     a20050111    1     2006032401
    2     a20050112    2     2006032402
    3     a20050113    3     2006032403
    4     a20050114    4     2006032404
    NULL     NULL     8     2006032408

    (所影响的行数为 5 行)
    结果说明:
    仔细观察一下,就会发现,和left join的结果刚好相反,这次是以右表(B)为基础的,A表不足的地方用NULL填充.
    --------------------------------------------
    3.inner join
    sql语句如下: 
    select * from A
    innerjoin B 
    on A.aID = B.bID

    结果如下:
    aID     aNum     bID     bName
    1     a20050111    1     2006032401
    2     a20050112    2     2006032402
    3     a20050113    3     2006032403
    4     a20050114    4     2006032404

    结果说明:
    很明显,这里只显示出了 A.aID = B.bID的记录.这说明inner join并不以谁为基础,它只显示符合条件的记录.

    4.查差集

    select a.* FROM A a left outer join B b on a.qq = b.qq
    WHERE b.qq is null;

    --------------------------------------------
    注: 
    LEFT JOIN操作用于在任何的 FROM 子句中,组合来源表的记录。使用 LEFT JOIN 运算来创建一个左边外部联接。左边外部联接将包含了从第一个(左边)开始的两个表中的全部记录,即使在第二个(右边)表中并没有相符值的记录。

    语法:FROM table1 LEFT JOIN table2 ON table1.field1 compopr table2.field2

    说明:table1, table2参数用于指定要将记录组合的表的名称。
    field1, field2参数指定被联接的字段的名称。且这些字段必须有相同的数据类型及包含相同类型的数据,但它们不需要有相同的名称。
    compopr参数指定关系比较运算符:"=", "<", ">", "<=", ">=" 或 "<>"。
    如果在INNER JOIN操作中要联接包含Memo 数据类型或 OLE Object 数据类型数据的字段,将会发生错误. 

    table a(id, type):

    id     type

    ----------------------------------

    1      1        

    2      1         

    3      2         

    table b(id, class):

    id    class

    ---------------------------------

    1      1

    2      2

    sql语句1:select a.*, b.* from a left join b on a.id = b.id and a.type = 1;

    sql语句2:select a.*, b.* from a left join b on a.id = b.id where a.type = 1;

    sql语句3:select a.*, b.* from a left join b on a.id = b.id and b.class = 1;

    sql语句1的执行结果为:

    a.id    a.type    b.id    b.class

    ----------------------------------------

    1        1            1        1

    2        1            2        2

    3        2              

    sql语句2的执行结果为:

    a.id    a.type    b.id    b.class

    ----------------------------------------

    1        1            1        1

    2        1            2        2

    sql语句3的执行结果为:

    a.id    a.type    b.id    b.class

    ----------------------------------------

    1        1            1        1

    2        1           

    3        2           

    由sql语句1可见,left join 中左表的全部记录将全部被查询显示,on 后面的条件对它不起作用,除非再后面再加上where来进行筛选,这就是sql语句2了;由sql语句3可见,on后面的条件中,右表的限制条件将会起作用。

    **********************************************************************************

    sql语句4:select a.*, b.* from a inner join b on a.id = b.id and a.type = 1;

    sql语句5:select a.*, b.* from a inner join b on a.id = b.id where a.type = 1;

    sql语句6:select a.*, b.* from a, b where a.id = b.id and a.type = 1;

    sql语句7:select a.*, b.* from a, b where a.type = 1 and a.id = b.id;

    这四条语句的执行结果一样,如下:

    a.id    a.type    b.id    b.class

    ----------------------------------------

    1        1            1        1

    2        1            2        2

    由此可见,inner join 中on后面的限制条件将全部起作用,这与where的执行结果是一样的。另外,where语句与inner join确实能得到相同的结果,只是效率不同(这个我没有测试过,不过我相信这个结论)。

    但是sql语句6是否比sql语句7的效率要低一些,我没有足够的数据量来测试,不过我也相信是如此的。

  • 相关阅读:
    Openstack-Mitaka Ceilometer 部署心得
    Openstack-Mitaka Keystone 部署心得
    IO模型学习笔记
    TCP-IP协议学习笔记
    大规模分类问题作业报告
    RabbitMQ安装笔记
    5.7.8.framebuffer驱动框架分析3
    5.7.7.framebuffer驱动框架分析2
    5.7.6.framebuffer驱动框架分析1
    5.7.5.framebuffer驱动框架总览
  • 原文地址:https://www.cnblogs.com/duanxz/p/2621268.html
Copyright © 2020-2023  润新知