第三章 联接查询 T-SQL语言基础
联接查询
sql server 2008支持四种表运算符----JOIN,APPLY,PIVOT,UNPIVOT.
JOIN表运算符是ANSI标准,而APPLY,PIVOT,UNPIVOT是T-SQL对标准的扩展
JOIN表运算符,联接有三种基本类型:交叉联接,内联接和外联接.
交叉联接只有一个步骤:笛卡尔积;内联接有两个步骤:笛卡尔积和过滤;外联接有三个步骤:笛卡尔积,过滤,添加外部行.
(逻辑查询处理和物理查询处理的不同!)
3.1 交叉联接 (cross join)
最简单的联接,只实现了一个逻辑查询步骤(笛卡尔积)
3.1.1 ANSI SQL-92
一般标准都是用 ANSI-SQL 92的
-- ANSI SQL-92
USE TSQLFundamentals2008; SELECT C.custid, E.empid
FROM Sales.Customers AS C
CROSS JOIN HR.Employees AS E;
3.1.2 ANSI SQL-89
-- ANSI SQL-89
SELECT C.custid, E.empid
FROM Sales.Customers AS C, HR.Employees AS E;
3.1.3 自交叉联接
对同一个表的多个实例也可以进行联接,这种功能就是所谓的自联接,所有基本联接类型(交叉联接,内联接,以及外联接)都是支持自联接.
-- Self Cross-Join
SELECT
E1.empid, E1.firstname, E1.lastname,
E2.empid, E2.firstname, E2.lastname
FROM HR.Employees AS E1
CROSS JOIN HR.Employees AS E2;
GO
--在自联接中,必须为表起别名.如果不为表指定别名,联接结果中的列名就会有歧义.
--自联接的笛卡尔积,与不是自联接的笛卡尔积不同!
3.1.4 生成数字表
自交叉联接的运用.
-- All numbers from - -- Auxiliary table of digits
USE tempdb;
IF OBJECT_ID('dbo.Digits', 'U') IS NOT NULL DROP TABLE dbo.Digits;
CREATE TABLE dbo.Digits(digit INT NOT NULL PRIMARY KEY); --2008特有的
INSERT INTO dbo.Digits(digit)
VALUES (),(),(),(),(),(),(),(),(),(); /*
Note:
Above INSERT syntax is new in Microsoft SQL Server 2008.
In earlier versions use: INSERT INTO dbo.Digits(digit) VALUES(0);
INSERT INTO dbo.Digits(digit) VALUES(1);
INSERT INTO dbo.Digits(digit) VALUES(2);
INSERT INTO dbo.Digits(digit) VALUES(3);
INSERT INTO dbo.Digits(digit) VALUES(4);
INSERT INTO dbo.Digits(digit) VALUES(5);
INSERT INTO dbo.Digits(digit) VALUES(6);
INSERT INTO dbo.Digits(digit) VALUES(7);
INSERT INTO dbo.Digits(digit) VALUES(8);
INSERT INTO dbo.Digits(digit) VALUES(9);
*/ SELECT digit FROM dbo.Digits;
GO -- All numbers from -
SELECT D3.digit * + D2.digit * + D1.digit + AS n
FROM dbo.Digits AS D1
CROSS JOIN dbo.Digits AS D2
CROSS JOIN dbo.Digits AS D3
ORDER BY n;
3.2 内联接
内联接要应用的两个逻辑查询处理步骤:首先像交叉联接一样,对两个输入表进行笛卡尔积运算;然后根据用户指定的谓词对结果进行过滤.
3.2.1 ANSI-SQL 92
ANSI-SQL 92:须在两个表名之间指定INNER JOIN关键字.
INNER关键字是可选的,因为内联接是默认的联接方式,所以可以只单独指定JOIN关键字.
用于对行进行过滤的谓词是在一个称为ON子句的特别设计的语句中指定的,该谓词也称为联接条件.
---------------------------------------------------------------------
-- INNER Joins
--------------------------------------------------------------------- -- ANSI SQL-92
USE TSQLFundamentals2008; SELECT E.empid, E.firstname, E.lastname, O.orderid
FROM HR.Employees AS E
JOIN Sales.Orders AS O
ON E.empid = O.empid;
--以上,在关系代数的基础上来考虑内联接,联接运算首先对两个表求笛卡尔积,然后根据条件E.empid = O.empid,对行进行过滤.
--与WHERE和HAVING子句类似,ON子句同样也只返回令谓词结果为TRUE的行,而不会返回令谓词计算结果为FALSE或UNKNOW的行.
3.2.2 ANSI-SQL 89
-- 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;
GO
--没有ON子句,不推荐使用!
3.2.3 更安全的内联接
-- Inner Join Safety
-- 采用ANSI-SQL 92的语法
SELECT E.empid, E.firstname, E.lastname, O.orderid
FROM HR.Employees AS El
JOIN Sales.Orders AS O;
GO SELECT E.empid, E.firstname, E.lastname, O.orderid
FROM HR.Employees AS E, Sales.Orders AS O;
GO
3.3 特殊的联接实例
特殊的联接实例包括:组合联接,不等联接,以及多表联接
3.3.1 组合联接
组合联接就是联接条件设计联接两边的多个列的查询.当需要根据主键-外键关系来联接两个表,而且主外键关系是组合的(即,关系基于多个列)时,通常就要使用组合联接.
例如:
SELECT * FROM TABLE1 AS T1 INNER JOIN TABLE2 AS T2 ON T1.COL1= T2.COL1 AND T1.COL2 = T2.COL2
---------------------------------------------------------------------
-- Composite Joins
--------------------------------------------------------------------- -- Audit table for updates against OrderDetails
USE TSQLFundamentals2008;
IF OBJECT_ID('Sales.OrderDetailsAudit', 'U') IS NOT NULL
DROP TABLE Sales.OrderDetailsAudit;
CREATE TABLE Sales.OrderDetailsAudit
(
lsn INT NOT NULL IDENTITY,
orderid INT NOT NULL,
productid INT NOT NULL,
dt DATETIME NOT NULL,
loginname sysname NOT NULL,
columnname sysname NOT NULL,
oldval SQL_VARIANT,
newval SQL_VARIANT,
CONSTRAINT PK_OrderDetailsAudit PRIMARY KEY(lsn),
CONSTRAINT FK_OrderDetailsAudit_OrderDetails
FOREIGN KEY(orderid, productid)
REFERENCES Sales.OrderDetails(orderid, productid)
); SELECT OD.orderid, OD.productid, OD.qty,
ODA.dt, ODA.loginname, ODA.oldval, ODA.newval
FROM Sales.OrderDetails AS OD
JOIN Sales.OrderDetailsAudit AS ODA
ON OD.orderid = ODA.orderid
AND OD.productid = ODA.productid
WHERE ODA.columnname = N'qty';
3.3.2 不等联接
如果联接条件只包含等号运算符,要么这样的联接叫做等值联接.如果联接条件包含除等号以外的其他运算符,那么这样的联接叫做不等联接.
---------------------------------------------------------------------
-- Non-Equi Joins
--------------------------------------------------------------------- -- Unique pairs of employees
SELECT
E1.empid, E1.firstname, E1.lastname,
E2.empid, E2.firstname, E2.lastname
FROM HR.Employees AS E1
JOIN HR.Employees AS E2
ON E1.empid < E2.empid;
--ON子句中指定的判断条件,目的是为了生存雇员之间的唯一配对组合.
--以上,使用内联接,并在联接条件中指定左边的键值要小于右边的键值!
3.3.3 多表联接
一个联接表运算符只对两个表进行操作,而一条查询语句可以包含多个联接.
当FROM子句中包含多个表运算符时,表运算符在逻辑上是按从左到右的顺序处理的.也就是,第一个表运算符的结果表将作为第二个表运算符的输入,第二个表运算符的结果将作为第三个表运算符左边的输入,以此类推!
---------------------------------------------------------------------
-- Multi-Table Joins
--------------------------------------------------------------------- SELECT
C.custid, C.companyname, O.orderid,
OD.productid, OD.qty
FROM Sales.Customers AS C
JOIN Sales.Orders AS O
ON C.custid = O.custid
JOIN Sales.OrderDetails AS OD
ON O.orderid = OD.orderid;
3.4 外联接
3.4.1 外联接基础
外联接是在ANSI-SQL 92中才被引入的,外联接的逻辑步骤有:1.笛卡尔积;2.ON 过滤器;3.添加外部行
在外联接中,要把一个表标记为"保留的"表;在表名之间使用关键字LEFT OUTER JOIN,RIGHT OUTER JOIN,以及FULL OUTER JOIN,其中OUTER关键字是可选的.
LEFT关键字表示左边表的行是保留的,RIGHT关键字表示右边表的行是保留的,而FULL关键字则表示左右两边表的行都是保留的.外联接的第三个逻辑查询处理步骤就是要识别保留表中按照ON条件在另一个表找不到与之匹配的那些行,再把这些行添加到联接的前两个步骤生成的结果表中;对于来自联接的非保留表的那些列,追加的外部行中额这些列则用NULL作为占位符.
-- Customers and their orders, including customers with no 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;
从外联接保留表的角度来看,可以认为外联接结果中的数据行包括两种:内部行和外部行.内部行是指按照ON子句中的条件能在联接的另一边找到匹配的那些行;而外部行则是指找不到匹配的那些行.内联接只返回内部行,而外联接同时返回内部行和外部行.
外联接中,ON子句中的过滤条件不是最终的.ON子句中的条件并不能最终决定保留表中部分行是否会在结果中出现,而只是判断是否能够匹配另一边表中的某些行.所以,当需要表达一个非最终的条件时,就在ON子句中指定联接条件.当在生成外部行之后,要应用过滤器,而且希望过滤条件是最终的,就应该在WHERE子句中指定.,对于行的过滤来说,WHERE子句是最终的.
-- Customers with no orders
SELECT C.custid, C.companyname
FROM Sales.Customers AS C
LEFT OUTER JOIN Sales.Orders AS O
ON C.custid = O.custid
WHERE O.orderid IS NULL;
GO
--以上,可以返回外部行,对于外部行,其来自联接的非保留表的列都标记为NULL,所以可以只筛选联接的非保留表的列值之一为NULL的那些行
--选择非保留表中的哪个列作为过滤器也很重要.应该选择只在外部行才取值为NULL,而在其他行取值不为NULL(例如,NULL值不能来自基本表)的某个列.可以考虑三种情况----主键列,联接列,以及定义为NOT NULL的列.\
--当查找NULL值时,应该使用 IS NULL 运算符.
3.4.2 外联接的高级主题
1.包含缺少值的数据
2.对外联接中非保留表的列值进行过滤
3.在多表联接中使用外联接
4.随外联接一起使用COUNT聚合函数
111
第三章 联接查询 T-SQL语言基础的更多相关文章
- Java Persistence with MyBatis 3(中文版) 第三章 使用XML配置SQL映射器
关系型数据库和SQL是经受时间考验和验证的数据存储机制.和其他的ORM 框架如Hibernate不同,MyBatis鼓励开发者可以直接使用数据库,而不是将其对开发者隐藏,因为这样可以充分发挥数据库服务 ...
- SQL语言基础和数据库操作
Sql语言基础: 核心思想:我们自己构造一段查询的代码,然后添加到语句后,从而得到想要的某些数据. Mysql是一种开源数据库 APP Serv:Apache+php+mysql,相当于phpstud ...
- PL/SQL语言基础
PL/SQL语言基础 进行PL/SQL编程前,要打开输出set serveroutput on 1.创建一个匿名PL/SQL块,将下列字符输出到屏幕:"My PL/SQL Block Wor ...
- 学习笔记:oracle学习三:SQL语言基础之sql语言简介、用户模式
目录 1.sql语言简介 1.1 sql语言特点 1.2 sql语言分类 1.3 sql语言的编写规则 2.用户模式 2.1 模式与模式对象 2.2 实例模式scott 本系列是作为学习笔记,用于记录 ...
- orcale 之 SQL 语言基础
SQL 全称是结构化查询语句(Structure Query Language),是数据库操作的国际化语言,对所有的数据库产品都要支持. SQL 语言的分类 我们按照其功能可以大致分为四类: 数据定义 ...
- 浅谈PL/SQL语言基础
在前面的学习中,我们大部分接触的都是SQL语言,但是,在实现复杂操作的时候,SQL语言就无能为力了,这时候就需要引入新的语言,PL/SQL语言就是对SQL语言的扩展,可以实现存储过程,函数等的创建.下 ...
- SQL语言基础-基本概念
SQL:IBM的圣约瑟(SanJose),SEQUEL 2(也就是现在的SQL语言) 1979.Oracle首先提出提供了商用的SQL语言 1986.10美国ANSI采用SQL作为关系数据库管理系统的 ...
- SQL语言基础
主要学习链接1 http://www.cnblogs.com/anding/p/5281558.html 搜索学习链接2 http://www.cnblogs.com/libingql/p/41342 ...
- 学习笔记:oracle学习三:SQL语言基础之检索数据:简单查询、筛选查询
目录 1. 检索数据 1.1 简单查询 1.1.1 检索所有列 1.1.2 检索指定的列 1.1.3 查询日期列 1.1.4 带有表达式的select语句 1.1.5 为列指定别名 1.1.6 显示不 ...
随机推荐
- VirtualBox——在Win7的HOST上安装配置虚拟机CentOS7
在Win7为HOST的环境下,安装VirtualBox,在其中安装CentOS7,以Bridge的方式搭建网络环境. 主要配置包括VirtualBox中的网络设置,以及CentOS中的网络配置.另外还 ...
- k8s环境部署(一)
环境介绍 1.单masrer节点 (安装下面图中介绍的四个组件) 2.俩个node节点(安装kubelet和docker) 3.为了支持master与node之前的通信,我们还需要在master上安装 ...
- Python中导入类
python导入类与导入函数,模块基本一样,一个模块fun,其中包含三个类 class Dog(): def __init__(self,name): self.name=name def bark( ...
- [django]update_or_create使用场景
update_or_create 作用是为了添加数据时防止重复. 先去查询, 如果没有在创建, 如果有则更新. update_or_create用法与密码存储实例 create方法 如果id是None ...
- python - 注释说明
归类三种注释风格: 大段的自定义块状注释 """ #========================================= # FileName: upgra ...
- vs2010 SetUp 安装软件时,界面出现乱码的问题
AppLocale在简体中文系统里使用之后, 会令某些简体中文的MSI形式的安装程序 显示乱码(比如: OFFICE2000简体中文版安装程序). 解决方法: 方法一: 卸载AppLocale即可解决 ...
- XML字符串和 java对象项目转换
这是之前写,仅供参考(如果缺少jar包可以私信我,CSDN现在下载的东西太费了,动不动就要积分,开源精神所剩无几了,也没办法都需要吃饭,可以理解) import javax.xml.bind.JAXB ...
- 內部作业 OH01 0001710000 无价格可确定
在CO15报工时,提示:“內部作業 OH01 0001710000 無價格可確定” 出现以上错误信息,表示没有在KP26维护价格, 只需要进入KP26维护成本中心和作业类型的价格即可, 具体操作如下图 ...
- SQLServer 断开数据库连接
数据库名:test1 1. 查询数据库当前连接 select * from master.sys.sysprocesses where dbid = db_id('test1') 2. 断开指定连接 ...
- JavaScript(3)——文档工具
文档工具 LEARN HTML = 教程 HTML REFERENCE = 字典 HTML + CSS + JAVASCRIPT = DYNAMIC HTML 推荐浏览器: Chrome浏览器(有丰 ...