• 连接条件和连接类型(内连接,等值连接,不等连接,外连接,左/右/全外连接)


      本文使用的数据来自《精通Oracle Database 12c SQL & PL/SQL编程(第三版)》。这里用到了两张表,products和product_types,分别为产品表和产品类型表。

      products的数据展示如下:

      

      product_types的数据展示如下:

      

      连接分为三中类型,即内连接,外连接自连接。内连接根据连接条件不同,可以分为等值连接不等连接。等值连接中使用的是等于操作符(=),不等连接在连接中使用除等号外的操作符(<,>,BETWEEN等);外连接根据保留数据的方向,分为左外连接、右外连接全外连接

      这里给出等值连接和内连接的比较:  

    -- 内连接
    SELECT p.name, pt.name
    FROM products p INNER JOIN product_types pt ON p.product_type_id = pt.product_type_id
    ORDER BY p.name;
    -- 等值连接
    SELECT p.name, pt.name
    FROM products p, product_types pt
    WHERE p.product_type_id = pt.product_type_id
    ORDER BY p.name;

      两者查询的结果一样,查询的效率也一样,可以看出通常情况下,内连接是默认使用等值连接的。

      二者的查询结果如下:

      

      二者在时间和空间的效率如下:

      

       等值连接的一个特殊情况是自然连接。自然连接是根据两个表中同名的列进行连接的,因为在实际操作中,经常需要明确指出根据哪些列连接,因此自然连接很少用。

      外连接分为左外连接、右外连接和全外连接。左外连接保留左表的所有行(如果右表没有匹配行,取空值),右外连接保留右表的所有行,全外连接保留左表和右表的所有行(取不到则另一侧留空)。

      其中左外连接可以通过LEFT JOIN,或在右表加(+)实现;其中右外连接可以通过RIGHT JOIN,或在左表加(+)实现;(+)总是在被保留数据的另一侧出现。

      全外连接只能通过FULL JOIN实现,不存在两边(+)的写法。

    -- 左外连接
    SELECT p.name, pt.name
    FROM products p, product_types pt
    WHERE p.product_type_id = pt.product_type_id(+)
    ORDER BY p.name;
    
    -- 左外连接2
    SELECT p.name, pt.name
    FROM products p LEFT JOIN product_types pt ON p.product_type_id = pt.product_type_id
    ORDER BY p.name;
    
    -- 右外连接
    SELECT p.name, pt.name
    FROM products p, product_types pt
    WHERE p.product_type_id(+) = pt.product_type_id
    ORDER BY p.name;
    
    -- 右外连接2
    SELECT p.name, pt.name
    FROM products p RIGHT JOIN product_types pt ON p.product_type_id = pt.product_type_id
    ORDER BY p.name
    
    -- 全外连接
    SELECT p.name, pt.name
    FROM products p FULL JOIN product_types pt ON p.product_type_id = pt.product_type_id
    ORDER BY p.name

      自连接一般用于有层级结构的,如员工表(查询某员工的上级都有谁),BOM(物料清单)等。这里暂不举例,后面再填坑。

      

      

      

  • 相关阅读:
    51NOD 1773:A国的贸易——题解
    BZOJ4553:[HEOI2016/TJOI2016]序列——题解
    BZOJ4597:[SHOI2016]随机序列——题解
    BZOJ1858:[SCOI2010]序列操作——题解
    BZOJ5157 & 洛谷3970:[TJOI2014]上升子序列——题解
    BZOJ3173:[TJOI2013]最长上升子序列 & HDU3564:Another LIS——题解
    BZOJ4755: [JSOI2016]扭动的回文串——题解
    洛谷2000:拯救世界——题解
    PPP中的PAP和CHAP的区别
    Linux C 实现一个简单的线程池
  • 原文地址:https://www.cnblogs.com/AlleyMeowy/p/10993060.html
Copyright © 2020-2023  润新知