zoukankan      html  css  js  c++  java
  • SQL中的left outer join,inner join,right outer join用法详解

    LEFT JOIN 关键字会从左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中没有匹配的行。
    LEFT JOIN 关键字语法
    SELECT column_name(s) FROM table_name1 LEFT JOIN table_name2 ON table_name1.column_name=table_name2.column_name 注释:在某些数据库中, LEFT JOIN 称为 LEFT OUTER JOIN。

    原始的表

    "Persons" 表:
    Id_P
    LastName
    FirstName
    Address
    City
    1
    Adams
    John
    Oxford Street
    London
    2
    Bush
    George
    Fifth Avenue
    New York
    3
    Carter
    Thomas
    Changan Street
    Beijing
    "Orders" 表:
    Id_O
    OrderNo
    Id_P
    1
    77895
    3
    2
    44678
    3
    3
    22456
    1
    4
    24562
    1
    5
    34764
    65
    现在,我们希望列出所有的人,以及他们的定购 - 如果有的话。
    您可以使用下面的 SELECT 语句:
    SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons LEFT JOIN Orders ON Persons.id_P=Orders.id_P ORDER BY Persons.LastName 结果集
    LastName
    FirstName
    OrderNo
    Adams
    John
    22456
    Adams
    John
    24562
    Carter
    Thomas
    77895
    Carter
    Thomas
    44678
    Bush
    George

      
    LEFT JOIN 关键字会从左表 (Persons) 那里返回所有的行,即使在右表 (Orders) 中没有匹配的行。

     这两天,在研究SQL语法中的inner join多表查询语法的用法,通过学习,发现一个SQL命令,竟然涉及到很多线性代数方面的知识,现将这些知识系统地记录如下:

          使用关系代数合并数据
    1 关系代数
    合并数据集合的理论基础是关系代数,它是由E.F.Codd于1970年提出的。
    在关系代数的形式化语言中:
    ?          用表、或者数据集合表示关系或者实体。
    ?          用行表示元组。
    ?          用列表示属性。
    关系代数包含以下8个关系运算符
    ?          选取――返回满足指定条件的行。
    ?          投影――从数据集合中返回指定的列。
    ?          笛卡尔积――是关系的乘法,它将分别来自两个数据集合中的行以所有可能的方式进行组合。
    ?          并――关系的加法和减法,它可以在行的方向上合并两个表中的数据,就像把一个表垒在另一个表之上一样。
    ?          交――返回两个数据集合所共有的行。
    ?          差――返回只属于一个数据集合的行。
    ?          连接――在水平方向上合并两个表,其方法是:将两个表中在共同数据项上相互匹配的那些行合并起来。
    ?          除――返回两个数据集之间的精确匹配。
    此外,作为一种实现现代关系代数运算的方法,SQL还提供了:
    ?          子查询――类似于连接,但更灵活;在外部查询中,方式可以使用表达式、列表或者数据集合的地方都可以使用子查询的结果。
    本章将主要讲述多种类型的连接、简单的和相关的子查询、几种类型的并、关系除以及其他的内容。
    2 使用连接
    2.1 连接类型
    在关系代数中,连接运算是由一个笛卡尔积运算和一个选取运算构成的。首先用笛卡尔积完成对两个数据集合的乘运算,然后对生成的结果集合进行选取运算,确保只把分别来自两个数据集合并且具有重叠部分的行合并在一起。连接的全部意义在于在水平方向上合并两个数据集合(通常是表),并产生一个新的结果集合,其方法是将一个数据源中的行于另一个数据源中和它匹配的行组合成一个新元组。
    SQL提供了多种类型的连接方式,它们之间的区别在于:从相互交叠的不同数据集合中选择用于连接的行时所采用的方法不同。
    连接类型          定义
    内连接          只连接匹配的行
    左外连接          包含左边表的全部行(不管右边的表中是否存在与它们匹配的行),以及右边表中全部匹配的行
    右外连接          包含右边表的全部行(不管左边的表中是否存在与它们匹配的行),以及左边表中全部匹配的行
    全外连接          包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行。
    (H)(theta)连接          使用等值以外的条件来匹配左、右两个表中的行
    交叉连接          生成笛卡尔积-它不使用任何匹配或者选取条件,而是直接将一个数据源中的每个行与另一个数据源的每个行都一一匹配
    在INFORMIX中连接表的查询
    如果FROM子句指定了多于一个表引用,则查询会连接来自多个表的行。连接条件指定各列之间(每个表至少一列)进行连接的关系。因为正在比较连接条件中的列,所以它们必须具有一致的数据类型。
    SELECT语句的FROM子句可以指定以下几种类型的连接
    FROM子句关键字          相应的结果集
    CROSS JOIN          笛卡尔乘积(所有可能的行对)
    INNER JOIN          仅对满足连接条件的CROSS中的列
    LEFT OUTER JOIN          一个表满足条件的行,和另一个表的所有行
    RIGHT OUTER JOIN          与LEFT相同,但两个表的角色互换
    FULL OUTER JOIN        LEFT OUTER 和 RIGHT OUTER中所有行的超集

    2.2 内连接(Inner Join
    内连接是最常见的一种连接,它页被称为普通连接,而E.FCodd最早称之为自然连接。
    下面是ANSI SQL-92标准
    select * 
    from    t_institution i 
    inner join t_teller t 
    on i.inst_no = t.inst_no
    where i.inst_no = "5801"
    其中inner可以省略。
    等价于早期的连接语法
    select * 
    from t_institution i, t_teller t 
    where i.inst_no = t.inst_no
    and i.inst_no = "5801"

    2.3 外连接
    2.3.1          左外连接(Left Outer Jion)
    select * 
    from    t_institution i 
    left outer join t_teller t 
    on i.inst_no = t.inst_no
    其中outer可以省略。
    2.3.2          右外连接(Rigt Outer Jion)
    select * 
    from    t_institution i 
    right outer join t_teller t 
    on i.inst_no = t.inst_no
    2.3.3          全外连接(Full Outer)
    全外连接返回参与连接的两个数据集合中的全部数据,无论它们是否具有与之相匹配的行。在功能上,它等价于对这两个数据集合分别进行左外连接和右外连接,然后再使用消去重复行的并操作将上述两个结果集合并为一个结果集。
    在现实生活中,参照完整性约束可以减少对于全外连接的使用,一般情况下左外连接就足够了。在数据库中没有利用清晰、规范的约束来防范错误数据情况下,全外连接就变得非常有用了,你可以使用它来清理数据库中的数据。
    select * 
    from    t_institution i 
    full outer join t_teller t 
    on i.inst_no = t.inst_no
    2.3.4          外连接与条件配合使用
    当在内连接查询中加入条件是,无论是将它加入到join子句,还是加入到where子句,其效果是完全一样的,但对于外连接情况就不同了。当把条件加入到join子句时,SQL Server、Informix会返回外连接表的全部行,然后使用指定的条件返回第二个表的行。如果将条件放到where子句中,SQL Server将会首先进行连接操作,然后使用where子句对连接后的行进行筛选。下面的两个查询展示了条件放置位子对执行结果的影响:
    条件在join子句
    select * 
    from    t_institution i 
    left outer join t_teller t 
    on i.inst_no = t.inst_no
    and i.inst_no = “5801”
    结果是:
    inst_no      inst_name              inst_no      teller_no    teller_name
    5801         天河区                 5801         0001         tom
    5801         天河区                 5801         0002         david
    5802         越秀区
    5803         白云区
    条件在where子句
    select * 
    from    t_institution i 
    left outer join t_teller t 
    on i.inst_no = t.inst_no
    where i.inst_no = “5801”
    结果是:
    inst_no      inst_name              inst_no      teller_no    teller_name
    5801         天河区                 5801         0001         tom
    5801         天河区                 5801         0002         david

    2.4 自身连接
    自身连接是指同一个表自己与自己进行连接。这种一元连接通常用于从自反关系(也称作递归关系)中抽取数据。例如人力资源数据库中雇员与老板的关系。
    下面例子是在机构表中查找本机构和上级机构的信息。
    select s.inst_no superior_inst, s.inst_name sup_inst_name, i.inst_no, i.inst_name
    from t_institution i
    join t_institution s
    on i.superior_inst = s.inst_no

    结果是:
    superior_inst sup_inst_name          inst_no      inst_name
    800             广州市                 5801         天河区
    800             广州市                 5802         越秀区
    800             广州市                 5803         白云区

    2.5 交叉(无限制) 连接
    交叉连接用于对两个源表进行纯关系代数的乘运算。它不使用连接条件来限制结果集合,而是将分别来自两个数据源中的行以所有可能的方式进行组合。数据集合中一的每个行都要与数据集合二中的每一个行分别组成一个新的行。例如,如果第一个数据源中有5个行,而第二个数据源中有4个行,那么在它们之间进行交叉连接就会产生20个行。人们将这种类型的结果集称为笛卡尔乘积。
    大多数交叉连接都是由于错误操作而造成的;但是它们却非常适合向数据库中填充例子数据,或者预先创建一些空行以便为程序执行期间所要填充的数据保留空间。
    select *
    from    t_institution i 
    cross join t_teller t
    在交叉连接中没有on条件子句
          通过以上知识,还真是系统地学习了一番,发现inner join其实可以通过最初的多表查询方式来实现,例如:

    select * from    t_institution i ,t_teller t where i.inst_no = t.inst_no and i.inst_no = "5801"

    其实,inner join就是对多表查询的一种解决方案而已。而外连接,还是有其特定的用处的,实际上就相当于一个开区间,而内连接就是一个闭区间。

  • 相关阅读:
    部署LVS-DR(直接路由)群集
    快速了解LVS负载均衡群集及部署LVS-NAT(地址转换)群集
    MySQL一些常用的高级SQL语句
    MySQL高可用群集MHA部署及故障测试
    MySQL的主从复制与读写分离
    你知道数据库中数据丢失的严重性吗,快来学习数据库的备份与恢复!!
    快速掌握mysql索引、事务与存储引擎知识以及使用命令
    MySQL数据库常用的一些管理操作
    带大家简单了解MySQL数据库
    剑指offer63-数据流中的中位数**
  • 原文地址:https://www.cnblogs.com/forever5325/p/9529131.html
Copyright © 2011-2022 走看看