浅谈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的主要工作是渲染.给 ...
随机推荐
- eclipse/myeclipse下简单更改tomcat的启动等待时间
1.双击server 2.更改timeout
- exit(0)、exit(1)、exit(-1)的区别
exit(0) - 正常退出 exit(1) - 异常退出(除0外,其他值均为异常退出)
- C++强制类型转换操作符 const_cast
const_cast也是一个强制类型转换操作符.<C++ Primer>中是这样描述它的: 1.将转换掉表达式的const性质. 2.只有使用const_cast才能将const性质性质转 ...
- 【BZOJ-3174】拯救小矮人 贪心 + DP
3174: [Tjoi2013]拯救小矮人 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 686 Solved: 357[Submit][Status ...
- 【BZOJ-3165】Segment 李超线段树(标记永久化)
3165: [Heoi2013]Segment Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 368 Solved: 148[Submit][Sta ...
- java的 clone方法
1.java语言中没有明确提供指针的概念与用法,而实质上每个new语句返回的都是一个指针的引用,只不过在大部分情况下开发人员不需要关心如果取操作这个指针而已. 2.在java中处理基本数据类型时,都是 ...
- 【poj1018】 Communication System
http://poj.org/problem?id=1018 (题目链接) 题意 要买n个产品,每个产品有m种价格和宽度(我也不知道翻译过来到底是什么?),设n个产品的宽度的最小值为B,n个产品的价格 ...
- 洛谷P1209 [USACO1.3]修理牛棚 Barn Repair
题目描述 在一个夜黑风高,下着暴风雨的夜晚,farmer John的牛棚的屋顶.门被吹飞了. 好在许多牛正在度假,所以牛棚没有住满. 牛棚一个紧挨着另一个被排成一行,牛就住在里面过夜. 有些牛棚里有牛 ...
- Getshell Via phpmyadmin SQL Execution In /import.php To Write Evil Webshell File Into Disk
目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 phpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上 ...
- 提高SQL的查询效率
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使 ...