• SQL 三种基本Join


    Join是关系型数据库系统的重要操作之一,SQL常用Join:内联接、外联接和交叉联接等。

    这里讨论一下这常用的三种连接。

    测试环境:db2 v10.1, linux 

    表定义:

     1 --用户
     2 CREATE TABLE USER
     3 (
     4 USERID INTEGER NOT NULL,
     5 COMPANYID INTEGER,
     6 TELNO VARCHAR(12)
     7 );
     8 
     9 --公司
    10 CREATE TABLE COMPANY
    11 (
    12 COMPANYID INTEGER NOT NULL,
    13 TELNO VARCHAR(12)
    14 );

    数据:

    --USER
    
    USERID      COMPANYID   TELNO       
    ----------- ----------- ------------
             11           2 777777      
             22           3 123456      
             33           4 567890  
    
    --COMPANY
    
    COMPANYID   TELNO       
    ----------- ------------
              2 888888   

    1. inner join

    [db2inst1@win ~]$ db2 "select * from user inner join company on user.companyid=company.companyid"
    
    USERID      COMPANYID   TELNO        COMPANYID   TELNO       
    ----------- ----------- ------------ ----------- ------------
             11           2 777777                 2 888888      
    
      1 record(s) selected.

    注意:内联接(Inner join)满足交换律:“A inner join B” 和 “B inner join A” 是相等的。

    查看访问计划:

    Optimized Statement:
    -------------------
    SELECT 
      Q2.USERID AS "USERID",
      Q2.COMPANYID AS "COMPANYID",
      Q2.TELNO AS "TELNO",
      Q1.COMPANYID AS "COMPANYID",
      Q1.TELNO AS "TELNO" 
    FROM 
      DB2INST1.COMPANY AS Q1,
      DB2INST1.USER AS Q2 
    WHERE 
      (Q2.COMPANYID = Q1.COMPANYID)
    
    Access Plan:
    -----------
        Total Cost:         13.5566
        Query Degree:        1
    
                  Rows 
                 RETURN
                 (   1)
                  Cost 
                   I/O 
                   |
                    1 
                 HSJOIN
                 (   2)
                 13.5566 
                    2 
             /-----+------
            3                1 
         TBSCAN           TBSCAN
         (   3)           (   4)
         6.77858          6.77776 
            1                1 
           |                |
            3                1 
     TABLE: DB2INST1  TABLE: DB2INST1
          USER            COMPANY
           Q2               Q1

    用HSJOIN的方式进行,DB2对此进行了重写。

    2. outer join

    外部联接保存一个或两个输入表的所有行,即使无法找到匹配联接谓词的行。

    [db2inst1@win ~]$ db2 "select * from user left outer join company on user.companyid=company.companyid"
    
    USERID      COMPANYID   TELNO        COMPANYID   TELNO       
    ----------- ----------- ------------ ----------- ------------
             11           2 777777                 2 888888      
             33           4 567890                 - -           
             22           3 123456                 - -           
    
      3 record(s) selected.
    [db2inst1@win ~]$ db2 "select * from user right outer join company on user.companyid=company.companyid"
    
    USERID      COMPANYID   TELNO        COMPANYID   TELNO       
    ----------- ----------- ------------ ----------- ------------
             11           2 777777                 2 888888      
    
      1 record(s) selected.

    查看访问计划:

    Optimized Statement:
    -------------------
    SELECT 
      Q2.USERID AS "USERID",
      Q2.COMPANYID AS "COMPANYID",
      Q2.TELNO AS "TELNO",
      Q1.COMPANYID AS "COMPANYID",
      Q1.TELNO AS "TELNO" 
    FROM 
      DB2INST1.COMPANY AS Q1 
      LEFT OUTER JOIN DB2INST1.USER AS Q2 
      ON (Q2.COMPANYID = Q1.COMPANYID)
    
    Access Plan:
    -----------
        Total Cost:         13.5566
        Query Degree:        1
    
                  Rows 
                 RETURN
                 (   1)
                  Cost 
                   I/O 
                   |
                    1 
                 HSJOIN<
                 (   2)
                 13.5566 
                    2 
             /-----+------
            3                1 
         TBSCAN           TBSCAN
         (   3)           (   4)
         6.77858          6.77776 
            1                1 
           |                |
            3                1 
     TABLE: DB2INST1  TABLE: DB2INST1
          USER            COMPANY
           Q2               Q1

    这里也是用的HSJOIN。

    3. cross join

    交叉联接(cross join)执行两个表的笛卡尔积(就是把表A和表B的数据进行一个N*M的组合)。也就是说,它匹配一个表与另一个表中的每一行;我们不能通过使用ON子句在交叉联接指定谓词,虽然我们可以使用WHERE子句来实现相同的结果,这是交叉联接基本上是作为一个内部联接了。

    [db2inst1@win ~]$ db2 "select * from user cross join company"
    
    USERID      COMPANYID   TELNO        COMPANYID   TELNO       
    ----------- ----------- ------------ ----------- ------------
             11           2 777777                 2 888888      
             22           3 123456                 2 888888      
             33           4 567890                 2 888888      
    
      3 record(s) selected.

    查看访问计划:

    Optimized Statement:
    -------------------
    SELECT 
      Q2.USERID AS "USERID",
      Q2.COMPANYID AS "COMPANYID",
      Q2.TELNO AS "TELNO",
      Q1.COMPANYID AS "COMPANYID",
      Q1.TELNO AS "TELNO" 
    FROM 
      DB2INST1.COMPANY AS Q1,
      DB2INST1.USER AS Q2
    
    Access Plan:
    -----------
        Total Cost:         13.5563
        Query Degree:        1
    
                  Rows 
                 RETURN
                 (   1)
                  Cost 
                   I/O 
                   |
                    3 
                 NLJOIN
                 (   2)
                 13.5563 
                    2 
             /-----+------
            1                3 
         TBSCAN           TBSCAN
         (   3)           (   4)
         6.77776          6.77858 
            1                1 
           |                |
            1                3 
     TABLE: DB2INST1  TABLE: DB2INST1
         COMPANY           USER
           Q1               Q2

    看到这里使用的是NLJOIN。

  • 相关阅读:
    https://github.com/zyq025/DotNetCoreStudyDemo/blob/main/HttpClientConsoleDemo/Program.cs
    NETCORE TASK多线程的使用
    .NetCore简单封装基于IHttpClientFactory的HttpClient请求
    Netcore中简单使用MemoryCache
    LinQ To Object 基本用法
    SelectMany 和 Select的区别
    List 转换成字符串
    【转】C#中enum的总结
    发个服务端包裹返回值的Response类和用法
    微软企业库 Microsoft Enterprise Library
  • 原文地址:https://www.cnblogs.com/jackhub/p/3170780.html
Copyright © 2020-2023  润新知