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

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

测试环境:db2 v10.1, linux

表定义:

 --用户
CREATE TABLE USER
(
USERID INTEGER NOT NULL,
COMPANYID INTEGER,
TELNO VARCHAR(12)
); --公司
CREATE TABLE COMPANY
(
COMPANYID INTEGER NOT NULL,
TELNO VARCHAR(12)
);

数据:

--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。

SQL 三种基本Join的更多相关文章

  1. Linq to Sql : 三种事务处理方式

    原文:Linq to Sql : 三种事务处理方式 Linq to SQL支持三种事务处理模型:显式本地事务.显式可分发事务.隐式事务.(from  MSDN: 事务 (LINQ to SQL)).M ...

  2. spark三种连接Join

    本文主要介绍spark join相关操作. 讲述spark连接相关的三个方法join,left-outer-join,right-outer-join,在这之前,我们用hiveSQL先跑出了结果以方便 ...

  3. [转]SQL三种获取自增长的ID方法

     最新更新请访问: http://denghejun.github.io   SQL SERVER中的三种获得自增长ID的方法  这个功能比较常用,所以记下来以防自己忘掉. SCOPE_IDENTIT ...

  4. Sql三种分页方法

    --分页三种方法--第一种 ROW_NUMBER() OVER( ORDER BY OrgID) AS indexs 大于pagesize*pageindex,少于等于pagesize*(pagein ...

  5. 递归算法+sql三种分页

    using Maticsoft.Common; using System; using System.Collections.Generic; using System.Data; using Sys ...

  6. Oracle三种循环例题:打印九九乘法表

    数据库SQL三种循环语句(For.While.Loop) --如果要将执行结果输出,需要先执行 setserveroutput on 命令,在窗口里显示服务器输出信息 set serveroutput ...

  7. SQL Server的三种物理连接之Loop Join(一)

    Sql Server有三种物理连接Loop Join,Merge Join,Hash Join, 当表之间连接的时候会选择其中之一,不同的连接产生的性能不同,理解这三种物理连接对性能调优有很大帮助. ...

  8. 浅谈SQL Server中的三种物理连接操作(HASH JOIN MERGE JOIN NESTED LOOP)

    简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...

  9. Spark SQL join的三种实现方式

    引言 join是SQL中的常用操作,良好的表结构能够将数据分散到不同的表中,使其符合某种规范(mysql三大范式),可以最大程度的减少数据冗余,更新容错等,而建立表和表之间关系的最佳方式就是join操 ...

随机推荐

  1. const vector<int> 和 vector<const int>问题讨论

    1.const vector <int> vec(10) —— 与const int a[10]是一回事,意思是vec只有10个元素,不能增加了,里面的元素也是不能变化的 vector&l ...

  2. protobuf转json

    方法介绍 protobuf的介绍在这里就不详细介绍了,主要是俺也是刚接触,感兴趣的同学可以去搜索相关博客或者直接去看源码以及google的官方文档(官方文档表示很吃力)或者去这个网站:https:// ...

  3. Django 学习笔记(二)

    Django 第一个 Hello World 项目 经过上一篇的安装,我们已经拥有了Django 框架 1.选择项目默认存放的地址 默认地址是C:\Users\Lee,也就是进入cmd控制台的地址,创 ...

  4. 用VS Code体验调试.NET Core 2.0 Preview (传统三层架构)

    准备工作 VS Code下载地址:https://vscode.cdn.azure.cn/stable/379d2efb5539b09112c793d3d9a413017d736f89/VSCodeS ...

  5. Redis配置文件redis.conf参数配置详解

    ########################################## 常规 ########################################## daemonize n ...

  6. JVM入门——运行时数据区

    这张图我相信基本上对JVM有点接触的都应该很熟悉,可以说这是JVM入门的第一课.其中的“堆”和“虚拟机栈(栈)”更是耳熟能详.下面将围绕这张图对JVM的运行时数据区做一个简单介绍. 程序计数器(Pro ...

  7. EntityManager 实例化方法

    Configure the EntityManager via a persistence.xml file <persistence xmlns="http://java.sun.c ...

  8. 设计模式 - 观察者模式(JDK)

    定义:观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新. 对象:    抽象主题角色:每个抽象主题角色都可以有任意数量的观察者.抽象主题提供可 ...

  9. C#面试题记录

    最怕的就是面试,每每到找工作的时候感觉压力山大,每次都要提前刷点题目去面对.所以这里自己对以后需要了解的知识做一个记录,方便自己随时的补充和深入了解,也给现在的自己留下一点点的印记,给未来留下一点回忆 ...

  10. 十年过去了,各位 .net 兄弟还好吗

    时间是最无情的,一下子就毕业10年了.很久没有发发牢骚了,今天突然想发一下.看过我文章喷过的知道,我一般都是散文,看完不知道我写了什么,形散而神不散嘛. 十年了,不好意思,没像网上说的标准一样,做管理 ...