SQL SERVER技术内幕之3 联接查询
JOIN表运算符对两个输入表进行操作。联接有三种基本类型:交叉联接、内联接和外联接。这三种联接的区别是它们采用的逻辑查询处理步骤各不相同,每种联接都有一套不同的步骤。交叉联接只有一个步骤----笛卡尔积;内联接有两个步骤----笛卡尔积、过滤;外联接有三个步骤----笛卡尔积、过滤、添加外部行。
3.1 交叉联接
SQL SERVER支持交叉联接的两种标准语法:ANSI SQL-92和ANSI SQL-89,推荐使用SQL-92的语法。
3.1.1 ANSI SQL-92语法
SELECT C.custid, E.empid
FROM Sales.Customers AS C
CROSS JOIN HR.Employees AS E;
使用ANSI SQL-92语法,要在参与联接的两个表之间使用"CROSS JOIN"关键字
3.1.2 ANSI SQL-89语法
SELECT C.custid, E.empid
FROM Sales.Customers AS C, HR.Employees AS E;
在这种语法中,只要简单地在表名之间加个逗号。
3.2 内联接
3.2.1 ANSI SQL-92
SELECT E.empid, E.firstname, E.lastname, O.orderid
FROM HR.Employees AS E
JOIN Sales.Orders AS O
ON E.empid = O.empid;
使用ANSI SQL-92语法,须在两个表名之间指定INNER JOIN关键字,INNER关键字是可选的,因为内联接是默认的联接方式。ON子句用于对行进行过滤,只返回计算结果为True的行,而不会返回令计算结果为False或UnKnown的行。
3.2.2 ANSI SQL-89
SELECT E.empid, E.firstname, E.lastname, O.orderid
FROM HR.Employees AS E, Sales.Orders AS O
WHERE E.empid = O.empid;
内联接也可以用ANSI SQL-89语法来表达,可以像交叉联接那样在表名之间放一个逗号,然后用WHERE子句定义联接条件。
3.2.3 为什么推荐使用ANSI SQL-92语法
1.假如你想写一条内联接查询,但不小心忘记指定联接条件,如果这时使用的是ANSI SQL-89语法,那么运行时不会出现异常信息,但执行的却是一个交叉查询。但如果此时使用的是ANSI SQL-92语法,那么语法分析器会报错。

2.假如你想写一条交叉联接查询,如果这时使用的是ANSI SQL-89语法,之后其他开发人员在查看或维护你的代码时,那么他们怎么会知道你想写的是一条交叉联接语句还是想写一条内联接语句,但却忘记了指定联接条件呢。但是如果你使用ANSI SQL-92语法,显示使用CROSS JOIN关键字,那么就可以显式的表达你想执行的是一条交叉联接。
3.3 外联接
外联接会应用内联接所应用的两个逻辑处理步骤(笛卡尔积和ON过滤),此外还多加一个外联接特有的第三步:添加外部行。在外联接中,要把一个表标记为"保留的表",可以在表名之间使用关键字 LEFT OUTER JOIN 、RIGHT OUTER JOIN 以及FULL OUTER JOIN,其中OUTER关键字是可选的。LEFT关键字表示左边表的行是保留的,RIGHT表示右边表的行是保留的,而FULL则表示左右两边表的行都是保留的。
外联接的第三个步骤就是要识别保留表中按照ON条件在另一个表找不到与之匹配的那些行,再把这些行添加到联接的前两个步骤生成的结果表中,对于来自联接的非保留表的那些列,追加的外部行中这些列则用NULL作为占位符。
以下的查询根据客户表的客户ID和订单表的客户ID对Customer表和Orders表进行联接,并返回客户和他们的订单信息。查询语句使用的联接类型是左外联接,所以查询结果也会返回那些没有发出任何订单的客户。
SELECT C.custid, C.companyname, O.orderid
FROM Sales.Customers AS C
LEFT OUTER JOIN Sales.Orders AS O
ON C.custid = O.custid;
假如现在只需要返回没有下任何订单的客户,或者用更技术性的话来讲,只需要返回外部行。则可以用下面的查询进行处理
SELECT C.custid, C.companyname, O.orderid
FROM Sales.Customers AS C
LEFT OUTER JOIN Sales.Orders AS O
ON C.custid = O.custid
WHERE O.orderid IS NULL;
返回外部行时,选择哪个列作为过滤器也很重要。应该选择只在外部行才取值为NULL,而在其他行取值不为NULL的某个列。有三种情形可以考虑安全地使用:主键列、联接列以及定义为NOT NULL的列。主键的列值不能为NULL,因此如果这样的列上出现了NULL,就意味着该行为外部行。如果某行的联接列为NULL值,则该行在联接的第二步就会被过滤掉,所以如果某行的联接列的值为NULL,则说明该行为外部行。同理,定义为NOT NULL的列上出现了NULL值,则该行明显也为外部行。
SQL SERVER技术内幕之3 联接查询的更多相关文章
- SQL SERVER技术内幕之6 集合查询
1.定义 集合运算会对两个输入查询的结果集进行逐行比较,根据比较结果和所使用的集合运算来确定某一行是否应该包含在集合运算的结果中.因为集合运算是针对集合之间进行的计算,所以集合运算涉及的两个查询不能包 ...
- SQL SERVER技术内幕之4 子查询
最外层查询的结果集会返回给调用者,称为外部查询.内部查询的结果是供外部查询使用的,也称为子查询.子查询可以分成独立子查询和相关子查询两类.独立子查询不依赖于它所属的外部查询,而相关子查询则须依赖它所属 ...
- SQL Server技术内幕笔记合集
SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...
- SQL SERVER技术内幕之10 可编程对象
一.变量 变量用于临时保存数据值,以供在声明它们的同一批处理语句中引用.例如,以下代码先声明一个数据类型为INT的变量@i,再将它赋值为10; DECLARE @i as INT; SET @i = ...
- SQL SERVER技术内幕之10 事务并发
1.事务 1.1事务的定义 事务是作为单个工作单元而执行的一系列操作.定义事务边界有显式和隐式两种.显式事务的定义以BEGIN TRAN作为开始,以COMMIT TRAN提交事务,以ROLLBACK ...
- SQL SERVER技术内幕之8 分组集
分组集就是分组(GROUP BY子句)使用的一组属性,在传统的SQL中,一个聚合查询只能定义一个分组集: 假设现在不想生成4个单独的结果集,而是希望生成一个统一的结果集,其中包含所有4个分组集的聚合 ...
- SQL SERVER技术内幕之5 表表达式
表表达式是一种命名的查询表达式,代表一个有效的关系表.可以像其他表一样,在数据处理语句中使用表表达式.SQL Server支持4种类型的表表达式:派生表(derived table).公用表表达式(C ...
- SQL SERVER技术内幕之7 透视与逆透视
1.透视转换 透视数据(pivoting)是一种把数据从行的状态旋转为列的状态的处理,在这个过程中可能须要对值进行聚合. 每个透视转换将涉及三个逻辑处理阶段,每个阶段都有相关的元素:分组阶段处理相关的 ...
- SQL Server中INNER JOIN与子查询IN的性能测试
这个月碰到几个人问我关于"SQL SERVER中INNER JOIN 与 IN两种写法的性能孰优孰劣?"这个问题.其实这个概括起来就是SQL Server中INNER JOIN与子 ...
随机推荐
- Django学习之mysql增删改查
上节介绍了如何使用命令行操作mysql增删改查,现在介绍如何使用python管理mysql 使用pip 下载完mysql后,mysql会以pymysql模块的形式存储在pycharm的包文件里.我们通 ...
- URL和报文知识总结 ——1
第一部分:浏览器生成的消息 关键词:URL的解析 HTTP请求的生成 DNS服务器 1.URL(网址)的构成: 对于一个网址的解析: https://i.cnblogs.com/index.htm ...
- 中国大学MOOC-C程序设计(浙大翁恺)—— 素数和
题目内容: 我们认为2是第一个素数,3是第二个素数,5是第三个素数,依次类推. 现在,给定两个整数n和m,0<n<=m<=200,你的程序要计算第n个素数到第m个素数之间所有的素数的 ...
- Java中的File.separator用法
在Windows下的路径分隔符和Linux下的路径分隔符是不一样的,当直接使用绝对路径时,跨平台会暴出“No such file or diretory”的异常. 比如说要在temp目录下建立一个te ...
- iOS 中的正则表达式符号
最近重新看了一遍 iOS 的正则文档,简单翻译下文档中涉及到的符号 1.正则表达式元字符 符号 说明 \a 响铃, \u0007 \A 匹配输入的开始,只匹配第一行,也就是忽略多行选项 \b 不在[] ...
- Spring的cache缓存介绍
从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该 ...
- andriod 学习三 使用android资源
3.1 android框架中有许多资源,包括布局,字符串,位图,图片....,使用资源之前需要在相应的资源文件中定义资源,然后编译程序时ADT将定义的资源转换成java类并给予唯一的id,而代码中需要 ...
- C# 浮点转时间
想了大半天实在想不出什么更适合文章的标题... 就现在这个标题,挺好- - 什么是浮点转时间呢? 今天写的一个计时功能,想来想去还是现在这种解决方案比较合适 先上一张图在来讲解比较明了 如图:赛车游戏 ...
- 「日常训练」Uncle Tom's Inherited Land*(HDU-1507)
题意与分析 题意是这样的:给你一个\(N\times M\)的图,其中有一些点不能放置\(1\times 2\)大小的矩形,矩形可以横着放可以竖着放,问剩下的格子中,最多能够放多少个矩形. 注意到是\ ...
- 应用UserDefaults储存游戏分数和最高分
应用UserDefaults储存游戏分数和最高分 我们在GameScene.swift里 private var currentScore:SKLabelNode! // 当前分数节点 private ...