浅谈T-SQL中的派生表和CTE
引言
表表达式是一种命名的查询表达式,代表一个有效的关系表。MSSQL支持4种类型的表表达式,它们分别是:派生表、公用表表达式(CTE)、视图以及内联表值函数。表表达式并不是物理上真实存在的对象,它们是虚拟的。对于表表达式的查询在数据库引擎内部都会转化为底层对象的查询。使用表表达式通常是体现在代码的逻辑方面,而不是性能方面。下面就让我妈来详细介绍每一种类型吧。
派生表
派生表也叫表子查询是在外部查询的FROM子句中定义的。派生表的存在范围是定义它的外部查询,只要外部查询一结束,派生表也就不存在了。下面我们来看一个使用派生表的例子。
假设需要返回所有的美国客户,使用派生表我们可以这样使用。
select custid,companyname from
(select custid,companyname from
Sales.Customers
where country=N'USA') as USACusts
我们看到了派生表的简单例子。要有效的定义任何类型的表表达式,必须满足下面三个条件。
不保证有一定的顺序
表表达式代表的是一个表,关系表的中的行是没有固定顺序的。所以表表达式不允许使用ORDER BY子句。唯一例外是在T-SQL中使用了TOP选项,在带有TOP选项的查询语句中,ORDER BY子句只有一个目的,那就是为TOP选项定义要筛选出哪些行,不用于通常数据显示的目的。表表达式也符合这一法则。
所有的列必须有名称
所有的列名必须唯一
派生表的多引用
我们知道派生表是在外部查询的FROM子句中定义的,其逻辑处理顺序并不优先于外部查询。当对外部查询的FROM子句进行处理时,派生表其实并不存在。因此,如果我们要引用派生表的多个实例时,必须基于同一查询去定义多个派生表。
假设我们需要对上面的例子进行自联接,使用派生表就会显得代码冗余,如下:
use insidetsql2008
select * from
(select custid,companyname from
Sales.Customers
where country=N'USA') as USACusts
inner join (select custid,companyname from
Sales.Customers
where country=N'USA') as USACusts1
on USACusts.custid=USACusts1.custid
我们看到其实我们是对同一张表进行联接,但是需要将代码定义多遍,这无疑造成代码的混乱和冗余。
公用表表达式(CTE)
公用表表达式是和派生表很相似的一种表表达式,与派生表相比,CTE有一些重要的优势。下面还是通过一个简单的例子来看学习CTE吧
还是最上面查询所有美国客户例子。
with USACusts as (
select custid,companyname from
Sales.Customers
where country=N'USA'
)select * from USACusts
和派生表一样,一旦外部查询结束,CTE的生命周期也就结束了。
我们知道派生表在多引用的情况下,会造成代码冗余,使用公用表表达式可以缓解这方面的问题,我们来看一个例子(还是上面派生表的那个例子)。
with USACusts as (
select custid,companyname from
Sales.Customers
where country=N'USA'
)
select * from USACusts
inner join USACusts as USACusts1
on USACusts.custid=USACusts1.custid
我们看到使用公用表表达式我们无需像派生表那样定义相同的查询语句,只需要将查询语句定义一边,然后可以进行引用即可。
浅谈T-SQL中的派生表和CTE的更多相关文章
- 浅谈 django Models中的跨表
跨表操作在数据库操作非常常用,虽然其会降低读取数据的性能,但是它能节约数据在硬盘中的占用,优化数据表的结构和各自之间的关系. 在sql中,一般跨表需要用到 join 关键字 select * from ...
- 浅谈C++11中的多线程(二)
摘要 本篇文章围绕以下几个问题展开: 进程和线程的区别 何为并发?C++中如何解决并发问题?C++中多线程的基本操作 浅谈C++11中的多线程(一) - 唯有自己强大 - 博客园 (cnblogs.c ...
- SQL中 将同一个表中的A列更新到B列,B列更新到A列
有网友在SKYPE问及,如标题,SQL中 将同一个表中的A列更新到B列,B列更新到A列. 其实这个不是问题,直接写更新语句即可,可以参考下面动画演示: SQL source code: CREATE ...
- 转: 浅谈C/C++中的指针和数组(二)
转自:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242419.html 浅谈C/C++中的指针和数组(二) 前面已经讨论了指针和数组 ...
- 转:浅谈C/C++中的指针和数组(一)
再次读的时候实践了一下代码,结果和原文不一致 error C2372: 'p' : redefinition; different types of indirection 不同类型的间接寻址 /// ...
- 转载 浅谈C/C++中的static和extern关键字
浅谈C/C++中的static和extern关键字 2011-04-21 16:57 海子 博客园 字号:T | T static是C++中常用的修饰符,它被用来控制变量的存贮方式和可见性.ext ...
- 浅谈C语言中的强符号、弱符号、强引用和弱引用
摘自http://www.jb51.net/article/56924.htm 浅谈C语言中的强符号.弱符号.强引用和弱引用 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2014- ...
- SQL中如何将一个表中的某一列的数据复制到另一个表中的某一列里
表一: SPRD PRD_NO SPC 001 NULL 002 NULL 003 NULL ... ...
- 浅谈关于QT中Webkit内核浏览器
关于QT中Webkit内核浏览器是本文要介绍的内容,主要是来学习QT中webkit中浏览器的使用.提起WebKit,大家自然而然地想到浏览器.作为浏览器内部的主要构件,WebKit的主要工作是渲染.给 ...
随机推荐
- adb错误解决
1.adb是什么?ADB全称Android Debug Bridge, 是android sdk里的一个工具,用这个工具可以直接操作管理android模拟器或者真实的andriod设备. 2.调试安卓 ...
- bzoj4349: 最小树形图&&bzoj2260: 商店购物
双倍经验大法吼 昨天发现不会最小属性图&朱刘算法啊 吓得我赶紧补了一发 朱刘算法模板题 #include <iostream> #include <cstdio> #i ...
- 浅谈malloc()与free()
malloc()与free() l 函数原型 malloc函数的函数原型为:void* malloc(unsigned int size),它根据参数指定的尺寸来分配内存块,并且返回一个void型指 ...
- Java多线程与并发库高级应用-传统线程同步通信技术
面试题: 子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着又 主线程循环100次,如此循环50次,请写出程序 /** * 子线程循环10次,接着主线程循环100次,接着又回到 ...
- bzoj1121: [POI2008]激光发射器SZK
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- TortoiseGit与GitHub项目关联设置
一.常规克隆GitHub上的项目: 1.在本地硬盘上放置项目的地方上[右键]->[Git 克隆]->在[url地址]上输入https的GitHub的链接,然后就是等待完成,之后即可完成拉取 ...
- ZOJ2314 Reactor Cooling
Reactor Cooling Time Limit: 5 Seconds Memory Limit: 32768 KB Special Judge The terrorist g ...
- DedeCMS顽固木马后门专杀工具V2.0实现方式研究
catalog . 安装及使用方式 . 检查DEDECMS是否为最新版本 . 检查默认安装(install)目录是否存在 . 检查默认后台目录(dede)是否存在 . 检查DedeCMS会员中心是否关 ...
- setjmp()、longjmp() Linux Exception Handling/Error Handling、no-local goto
目录 . 应用场景 . Use Case Code Analysis . 和setjmp.longjmp有关的glibc and eglibc 2.5, 2.7, 2.13 - Buffer Over ...
- MongoDB: 数据库复制
db.copyDatabase("from","to","127.0.0.1:16161"); 将127.0.0.1上的from库.拷贝到t ...