联接(CROSS JOIN、JOIN、OUTER JOIN)
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
外部联接及数字表的应用
包含缺失值
在查询数据时,可以使用外部联接标识和包含缺失值。要求确保在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)相关推荐
- SQL中inner join、outer join和cross join的区别
对于SQL中inner join.outer join和cross join的区别很多人不知道,我也是别人问起,才查找资料看了下,跟自己之前的认识差不多,如果你使用join连表,缺陷的情况下是inne ...
- 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= ...
- 如何判断SAP CDS view的association是inner join还是outer join实现的
I have used the following syntax to directly return the corresponding description via path expressio ...
- inner join 和outer join的区别
1.inner join 和outer join的区别 inner join 和 outer join 是sql语言中的两种联表查询语句 假设,A,B两表各有一个字段 A B1 22 33 54 45 ...
- inner join和outer join的区别
假设你要join两个没有重复列的表,这是最常见的情况: inner join A 和 B 获得的是A和B的交集(intersect),即韦恩图(venn diagram) 相交的部分. outer ...
- 案例理解LEFT JOIN、RIGHT JOIN、INNER JOIN、OUTER JOIN 相关的 7 种用法
文章目录 建立相关表 七大JOIN Inner JOIN Left JOIN Left Excluding JOIN Right JOIN Right Excluding JOIN FULL Oute ...
- 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 ...
- 转载:left join right join left outer join 区别
原文地址:https://blog.csdn.net/laolaowhn/article/details/1776219 通俗的讲: A left join B 的连接的记录数 ...
- “INNER JOIN”和“OUTER JOIN”有什么区别?
问题描述: 另外,LEFT JOIN.RIGHT JOIN 和 FULL JOIN 如何适应? 保持自己快人一步,享受全网独家提供的一站式外包任务.远程工作.创意产品订阅服务–huntsbot.com ...
最新文章
- 【杭电ACM】1097 A hard puzzle
- Android视频播放之VideoView
- 【赠书】掌握人工智能重要主题,深度强化学习实践书籍推荐
- linux下文件夹压缩解压.tar , .gz , .tar.gz , .bz2 , .tar.bz2 , .bz , .tar.bz , .zip , .rar
- 树莓派开机运行python脚本_【树莓派】开机自启动脚本方法之一(.Desktop文件)...
- JS-copy到剪贴板
- Flow monitoring in Software-Defined Networks
- slope one matlab代码,经典推荐算法之 Slope one
- 云图说|ModelArts Pro:让AI开发更简单
- JAVA设计模式初探之桥接模式
- 用VS2008做博客¥(^_^)¥
- 洛谷 P4568 [JLOI2011]飞行路线
- 单片机:LCD1602
- python编程星期几_python如何获取星期几
- Bootstrap文字排版
- 秋天下载中心统计系统 入门安装
- [羊城杯 2020]A Piece Of Java
- Conventional Commits那些事
- 英伟达驱动安装成功之后,指令nvidia-smi表格里有ERR!
- 【NLP】动手实现一个句子生成器
热门文章
- android 模拟器网易,网易MuMu全游戏平台 网易mumu模拟器
- ARM linux解析之压缩内核zImage的启动过程
- 讲一下创业公司的技术架构演进
- 揭秘中国网络虚假新闻“制造器”,看传播者如何操纵操纵大众舆论?
- 打造数智制造“新引擎”,用友U9 cloud助百得胜加速崛起
- 计蒜客 god of gambler
- VC学习路线书籍+视频
- 我这些年对游戏外挂辅助开发的一些心得和体会
- 2022-2028年中国燃气轮机行业市场专项调研及投资前景研究报告
- 百度文件下载慢怎么办?~教你百度网盘无需VIP离线下载大文件