JOIN 表运算符对两个输入表进行操作。联接的类型有交叉联接、内部联接和外部联接,它们的区别在于如何应用逻辑查询处理阶段。交叉联接仅应用一个阶段——笛卡尔乘积,内部联接应用两个阶段——笛卡尔乘积和筛选,外部联接应用三个阶段——笛卡尔乘积、筛选和添加外部行。

交叉联接(CROSS JOIN)

交叉联接仅执行一个逻辑查询处理阶段——笛卡尔乘积,这一阶段对提供的两个输入表进行操作,联接并生成两个表的笛卡尔乘积(将一个输入表的每一行与另一个表的所有行匹配,得到m×n行)。

 -- 如果为表分配了别名,那么使用完整表名称作为前缀是无效的SELECT A.City, B.Company FROM Cities A CROSS JOIN Companies B  -- 推荐SELECT A.City, B.Company FROM Cities A, Companies B

自联接是指联接同一个表的多个实例,自联接被所有基本联接类型支持(交叉联接、内部联接、外部联接)。

 -- 自联接中必须为表指定别名,否则联接结果中所有列名都将不明确SELECT A.City, A.CityID, B.City, B.CityID FROM Cities A CROSS JOIN Cities B

交叉联接的一种用途是生成数字表(一个整数数列结果集)。

IF OBJECT_ID(N'dbo.Digits', 'U') IS NOT NULLDROP TABLE dbo.Digits;CREATE TABLE dbo.Digits
(digit INT NOT NULL PRIMARY KEY
)INSERT INTO dbo.Digits(digit) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)SELECTNum = A.digit * 100 + B.digit * 10 + C.digit + 1  -- 1~1000
FROMDigits A CROSS JOINDigits B CROSS JOINDigits C
ORDER BY Num

内部联接(INNER JOIN、JOIN)

内部联接应用两个逻辑查询处理阶段——首先对作为交叉联接的两个输入表应用一个笛卡尔乘积,然后按照指定的谓词筛选行。内部联接是在表名称之间指定 INNER JOIN 关键字。因为内部联接是默认链接,所以 INNER 关键字是可选的,可以仅指定 JOIN 关键字。指定的谓词(联接条件)用于在 ON 的子句中筛选行。

SELECT A.empid, A.firstname,A.lastname, B.orderid
FROM HR.Employees A JOIN Sales.Orders B ON A.empid=B.empid

联接的正确思考方式是基于关系代数,联接首先执行两个表的笛卡尔乘积,然后基于谓词筛选行。
内部联接可以在表名称之间指定一个逗号,然后在 WHERE 子句中指定联接条件:

SELECT A.empid, A.firstname,A.lastname, B.orderid
FROM HR.Employees A, Sales.Orders B WHERE A.empid=B.empid

但是,在复杂的具有多个表、筛选和其他查询元素的语句中,忘记在 WHERE 子句中指定联接条件的可能性会增加,这样可能就会误以为是一个交叉联接(无法区分是一个正确的交叉联接,还是一个错误的内部联接)。

其他

复合联接

复合联接是谓词涉及每侧多个属性的简单联接。

SELECTA.CityID, A.CreateTime, B.ProvinceID, B.Domain
FROMTest1 A JOIN Test2 BON A.ProvinceID=B.ProvinceID AND A.CityID=B.CityID
WHERE A.CreateTime='20180801'

当联接条件仅涉及等号运算符时,联接称为相等联接。当联接条件涉及除等号外的任何运算符时,联接称为不等联接(Non-equi join)。

-- 一定要先考虑笛卡尔乘积
SELECTA.empid, A.firstname, A.lastname, B.empid, B.firstname, B.lastname
FROM HR.Employees A JOIN HR.Employees B ON A.empid<B.empid
多联接查询

联接表运算符仅操作两个表,但是单个查询可以有多个联接。当 FROM 子句中出现多个表运算符时,表运算符一般从左到右进行逻辑处理。第一个表运算符的结果表将被视为第二个表运算符的左侧输入,第二个表运算符的结果将被视为第三表运算符的左侧输入,以此类推。

SELECTA.custid, A.companyname, B.orderid, C.productid, C.qty
FROMSales.Customers A JOINSales.Orders B ON A.custid=B.custid JOINSales.OrderDetails C ON B.orderid=C.orderid

外部联接(OUTER JOIN)

外部联接应用三个逻辑查询处理阶段——笛卡尔乘积、ON 筛选和添加外部行。外联接包括 LEFT OUTER JOIN、RIGHT OUTER JOIN 和 FULL OUTER JOIN,OUTER 关键字是可选的。外部联接的第三个逻辑查询处理阶段识别保留表中基于 ON 谓词未能与另一个表匹配的行,添加这些行到前两个联接阶段生成的结果表中,并对于联接非保留侧的属性使用 NULL 作为占位符。

SELECT A.custid, A.companyname, B.orderid
FROM Sales.Customers A LEFT JOIN Sales.Orders B on A.custid=B.custid

针对外部联接的保留侧,可以分为内部行外部行。内部行时基于谓词与另一侧匹配的行,外部行则是未匹配的行。内部联接仅返回内部行,而外部联接返回内部行和外部行。所以以下两种方式都可以返回内部行结果:

-- WHERE 筛选出内部行
SELECT A.custid, A.companyname, B.orderid
FROM Sales.Customers A LEFT JOIN Sales.Orders B on A.custid=B.custid
WHERE B.orderid IS NOT NULL  -- 因为添加的外部行用 NULL 作为占位符SELECT A.custid, A.companyname, B.orderid
FROM Sales.Customers A INNER JOIN Sales.Orders B on A.custid=B.custid

外部联接及数字表的应用

  1. 包含缺失值
    在查询数据时,可以使用外部联接标识和包含缺失值。要求确保在2006.1.1日到2008.12.31日中每天至少有一行输出,对于范围内具有的日期不做任何操作,但希望输出包含没有的日期,使用 NULL 标记作为占位符。

    -- 首先通过数字表获取需要查询范围的完整日期列表
    SELECT orderdate=DATEADD(D, A.n, '20051231')
    FROM dbo.Nums A
    WHERE A.n<DATEDIFF(D, '20051231', '20090101') ORDER BY orderdate-- 然后通过左外联接添加外部行
    SELECTorderdate=DATEADD(D, A.n, '20051231'), B.orderid, B.custid, B.empid
    FROMdbo.Nums A LEFT JOINSales.Orders B ON DATEADD(D, A.n, '20051231')=B.orderdate
    WHERE A.n<DATEDIFF(D, '20051231', '20090101') ORDER BY orderdate
    

联接(CROSS JOIN、JOIN、OUTER JOIN)相关推荐

  1. SQL中inner join、outer join和cross join的区别

    对于SQL中inner join.outer join和cross join的区别很多人不知道,我也是别人问起,才查找资料看了下,跟自己之前的认识差不多,如果你使用join连表,缺陷的情况下是inne ...

  2. SQL中的left outer join,inner join,right outer join用法 (左右内连接)

    SQL语句中的left outer join,inner join,right outer join用法 left outer join=left join ,   right outer join= ...

  3. 如何判断SAP CDS view的association是inner join还是outer join实现的

    I have used the following syntax to directly return the corresponding description via path expressio ...

  4. inner join 和outer join的区别

    1.inner join 和outer join的区别 inner join 和 outer join 是sql语言中的两种联表查询语句 假设,A,B两表各有一个字段 A B1 22 33 54 45 ...

  5. inner join和outer join的区别

    假设你要join两个没有重复列的表,这是最常见的情况: inner join  A 和 B 获得的是A和B的交集(intersect),即韦恩图(venn diagram) 相交的部分. outer ...

  6. 案例理解LEFT JOIN、RIGHT JOIN、INNER JOIN、OUTER JOIN 相关的 7 种用法

    文章目录 建立相关表 七大JOIN Inner JOIN Left JOIN Left Excluding JOIN Right JOIN Right Excluding JOIN FULL Oute ...

  7. SQL中inner join、left join、right join、outer join之间的区别

    SQL中inner join.left join.right join.outer join之间的区别 举个例子你就能知道了! A表(a1,b1,c1)      B表(a2,b2) a1   b1  ...

  8. 转载:left join right join left outer join 区别

    原文地址:https://blog.csdn.net/laolaowhn/article/details/1776219 通俗的讲:     A   left   join   B   的连接的记录数 ...

  9. “INNER JOIN”和“OUTER JOIN”有什么区别?

    问题描述: 另外,LEFT JOIN.RIGHT JOIN 和 FULL JOIN 如何适应? 保持自己快人一步,享受全网独家提供的一站式外包任务.远程工作.创意产品订阅服务–huntsbot.com ...

最新文章

  1. 【杭电ACM】1097 A hard puzzle
  2. Android视频播放之VideoView
  3. 【赠书】掌握人工智能重要主题,深度强化学习实践书籍推荐
  4. linux下文件夹压缩解压.tar , .gz , .tar.gz , .bz2 , .tar.bz2 , .bz , .tar.bz , .zip , .rar
  5. 树莓派开机运行python脚本_【树莓派】开机自启动脚本方法之一(.Desktop文件)...
  6. JS-copy到剪贴板
  7. Flow monitoring in Software-Defined Networks
  8. slope one matlab代码,经典推荐算法之 Slope one
  9. 云图说|ModelArts Pro:让AI开发更简单
  10. JAVA设计模式初探之桥接模式
  11. 用VS2008做博客¥(^_^)¥
  12. 洛谷 P4568 [JLOI2011]飞行路线
  13. 单片机:LCD1602
  14. python编程星期几_python如何获取星期几
  15. Bootstrap文字排版
  16. 秋天下载中心统计系统 入门安装
  17. [羊城杯 2020]A Piece Of Java
  18. Conventional Commits那些事
  19. 英伟达驱动安装成功之后,指令nvidia-smi表格里有ERR!
  20. 【NLP】动手实现一个句子生成器

热门文章

  1. android 模拟器网易,网易MuMu全游戏平台 网易mumu模拟器
  2. ARM linux解析之压缩内核zImage的启动过程
  3. 讲一下创业公司的技术架构演进
  4. 揭秘中国网络虚假新闻“制造器”,看传播者如何操纵操纵大众舆论?
  5. 打造数智制造“新引擎”,用友U9 cloud助百得胜加速崛起
  6. 计蒜客 god of gambler
  7. VC学习路线书籍+视频
  8. 我这些年对游戏外挂辅助开发的一些心得和体会
  9. 2022-2028年中国燃气轮机行业市场专项调研及投资前景研究报告
  10. 百度文件下载慢怎么办?~教你百度网盘无需VIP离线下载大文件