SQLServer中的CTE通用表表达式
Figure 1 被查询的视图CREATE VIEW vwMyView AS
SELECT
EmployeeID, COUNT(*) AS NumOrders, MAX(OrderDate) AS MaxDate
FROM Orders
GROUP BY EmployeeID
GO SELECT
e.EmployeeID, oe.NumOrders, oe.MaxDate, e.ReportsTo AS ManagerID,
om.NumOrders, om.MaxDate
FROM
Employees AS e
INNER JOIN vwMyView AS oe ON e.EmployeeID = oe.EmployeeID
INNER JOIN vwMyView AS om ON e.ReportsTo = om.EmployeeID
Figure 2 使用派生表的查询 SELECT
e.EmployeeID, oe.NumOrders, oe.MaxDate, e.ReportsTo AS ManagerID,
om.NumOrders, om.MaxDate
FROM
Employees AS e
INNER JOIN
(SELECT EmployeeID, COUNT(*), MAX(OrderDate)
FROM Orders
GROUP BY EmployeeID) AS oe(EmployeeID, NumOrders, MaxDate)
ON e.EmployeeID = oe.EmployeeID
LEFT JOIN
(SELECT EmployeeID, COUNT(*), MAX(OrderDate)
FROM Orders
GROUP BY EmployeeID) AS om(EmployeeID, NumOrders, MaxDate)
ON e.ReportsTo = om.EmployeeID
CTE 非常适用于此类情形,因为它提升了 T-SQL 的可读性(就像视图一样),而且能在同一个批处理后紧跟的查询中多次使用。当然,超出该范围它就不适用了。另外,CTE 是语言级别的构造,也就是说 SQL Server 不会在内部创建临时表或虚拟表。每次在紧随其后的查询中引用 CTE 的底层查询时都会调用它。
Figure 3 使用 CTE 查询;WITH EmpOrdersCTE (EmployeeID, NumOrders, MaxDate) AS
(
SELECT EmployeeID, COUNT(*), MAX(OrderDate)
FROM Orders
GROUP BY EmployeeID
) SELECT
e.EmployeeID, oe.NumOrders, oe.MaxDate,
e.ReportsTo AS ManagerID, om.NumOrders, om.MaxDate
FROM
Employees AS e
INNER JOIN EmpOrdersCTE oe ON e.EmployeeID = oe.EmployeeID
LEFT JOIN EmpOrdersCTE om ON e.ReportsTo = om.EmployeeID
;WITH myCTE (CustID, Co) AS
(
SELECT CustomerID, CompanyName FROM Customers
)
SELECT CustID, Co FROM myCTE
;WITH myCTE (CustID, Co) AS
(
SELECT CustomerID, CompanyName FROM Customers
)
SELECT CompanyName FROM Customers WHERE CustomerID = 'ALFKI'
SELECT CustID, Co FROM myCTE
;WITH myCTE AS
(
SELECT c.CustomerID, c.CompanyName, o.OrderID, o.OrderDate
FROM Customers c
INNER JOIN Orders o ON c.CustomerID = o.CustomerID
) SELECT CustomerID, CompanyName, OrderID, OrderDate
FROM myCTE FOR XML AUTO
一旦定义了 CTE,跟随其后的首个查询便能多次引用它。这一功能在某个查询需要多次引用 CTE 时尤为有用。图 3 中的代码示例演示了查询如何引用 EmpOrdersCTE 两次,以便能获取员工和主管的信息。当需要多次引用同一行集时,这非常有用;引用 CTE 两次比复制该查询要简单得多。
Figure 4 引用另一个 CTE 的 CTE;WITH
EmpOrdersCTE (EmployeeID, NumOrders)
AS
(
SELECT EmployeeID, COUNT(*)
FROM Orders
GROUP BY EmployeeID
),
MinMaxOrdersCTE (Mn, Mx, Diff)
AS
(
SELECT MIN(NumOrders), MAX(NumOrders), AVG(NumOrders)
FROM EmpOrdersCTE
)
SELECT Mn, Mx, Diff
FROM MinMaxOrdersCTE
- 创建一个返回顶层(这是定位点成员)的查询。
- 编写一个递归查询(这是递归成员)。
- 通过 UNION 将第一个查询与递归查询结合起来。
- 确保存在没有行会被返回的情况(这是终止检查)。
;WITH myRecursiveCTE(col1, col2, ... coln) AS
(
-- 定位点成员 查询
UNION ALL
-- 递归成员 查询来自CTE的自身数据
)
-- DEFINE YOUR CTE HERE
SELECT * FROM EmpCTE
OPTION (MAXRECURSION 7)
- SELECT DISTINCT
- GROUP BY
- HAVING
- TOP
- LEFT/RIGHT OUTER JOIN
Figure 5 递归收集销售人员;WITH EmpCTE(EmployeeID, EmployeeFirstName,
EmployeeLastName, MgrID, SalesLevel)
AS
(
-- 定位点成员
SELECT EmployeeID, FirstName, LastName, ReportsTo, 0
FROM Employees
WHERE EmployeeID = 2 -- Start with the VP of Sales UNION ALL -- 递归成员
SELECT
e.EmployeeID, e.FirstName, e.LastName, e.ReportsTo, m.SalesLevel+1
FROM
Employees AS e
INNER JOIN EmpCTE m ON e.ReportsTo = m.EmployeeID
) -- 使用CTE
SELECT EmployeeID, EmployeeFirstName, EmployeeLastName,
MgrID, SalesLevel
FROM EmpCTE
SQLServer中的CTE通用表表达式的更多相关文章
- SQLServer中的CTE(Common Table Expression)通用表表达式使用详解
概述 我们经常会编写由基本的 SELECT/FROM/WHERE 类型的语句派生而来的复杂 SQL 语句.其中一种方案是需要编写在 FROM 子句内使用派生表(也称为内联视图)的 Transact-S ...
- Sql Server系列:通用表表达式CTE
1 CTE语法WITH关键字 通用表表达式(Common Table Express, CTE),将派生表定义在查询的最前面.要使用CTE开始创建一个查询,可以使用WITH关键字. CTE语法: WI ...
- sql中with的用法(CTE公用表表达式):应用子查询嵌套,提高sql性能
一.WITH AS的含义 WITH AS短语,也叫子查询部分(subquery factoring),定义一个SQL片断,该片断会被整个SQL语句所用到. 有时是为了让SQL语句的可读性更高些,也可能 ...
- SQL Server CET 通用表表达式 之 精典递归
SQL2005 Common Table Expressions(CET)即通用表表达式. SQLSERVER CET递归使用案例: 1.普通案例 表结构如下: ;WITH cet_depart ...
- 关于使用CTE(公用表表达式)的递归查询
--关于使用CTE(公用表表达式)的递归查询 --CTE 的基本语法结构如下: WITH expression_name [ ( column_name [,...n] ) ] AS ( CTE_qu ...
- mysql 和 sqlserver中备份一张表的区别
sqlserver中备份一张表 SELECT * into qa_buglist_bak FROM qa_buglist 不管表的数据有多大,速度很快: mysql中上述语句就无效了,须得新建一张表, ...
- SQLServer中查询表结构(表主键 、列说明、列数据类型、所有表名)的Sql语句
SQLServer中查询表结构(表主键 .列说明.列数据类型.所有表名)的Sql语句 1.查询数据库中的所有表名称: SELECT name FROM SysObjects Where XType=' ...
- Sql — CTE公用表表达式和With用法总结
CTE(Common Table Expression) 公用表表达式,它是在单个语句的执行范围内定义的临时结果集,只在查询期间有效.它可以自引用,也可在同一查询中多次引用,实现了代码段的重复利用. ...
- 【转】CTE(公用表表达式)
本文转自:爽朗的微笑 http://www.cnblogs.com/shuangnet/archive/2013/03/22/2975929.html 公用表表达式 (CTE) 具有一个重要的优点, ...
随机推荐
- 【JVM】JVM垃圾收集器、垃圾收集算法、无用对象
Java 常见的垃圾收集器有哪些 实际上,垃圾收集器(GC,Garbage Collector)是和具体 JVM 实现紧密相关的,不同厂商(IBM.Oracle),不同版本的JVM,提供的选择也不同. ...
- 「线性基」学习笔记and乱口胡总结
还以为是什么非常高大上的东西花了1h不到就学好了 线性基 线性基可以在\(O(nlogx)\)的时间内计算出\(n\)个数的最大异或和(不需要相邻). 上述中\(x\)表示的最大的数. 如何实现 定义 ...
- apache beam ElasticSearchIO 遇到异常后job中断执行 自己定制beam IO
可以将 ElasticSearchIO.java 源码拷贝至自己的项目.改名为MyElasticSearchIO.java.自己定制实现.这时编译会遇到auto.value失败.在pom.xml中加入 ...
- 大数质因解:浅谈Miller-Rabin和Pollard-Rho算法
2017-07-19 08:54 Amphetamine:能发一下代码吗? 应我那位谜一样好友的邀约,我打算好好看一看Miller-Rabin和Pollard-Rho算法.很奇怪,各种地方有很多代码描 ...
- Sobel 边缘检测算子
转自:http://blog.csdn.net/xiaqunfeng123/article/details/17302003 Sobel 算子是一个离散微分算子 (discrete different ...
- MySQL学习笔记(四)悲观锁与乐观锁
恼骚 最近在搞并发的问题,订单的异步通知和主动查询会存在并发的问题,用到了Mysql数据库的 for update 锁 在TP5直接通过lock(true),用于数据库的锁机制 Db::name('p ...
- topshelf 服务启动运行
topshlf 服务启动运行方式 安装:servicename.exe install 启动:servicename.exe start 卸载:servicename.exe uninstall
- 开发portlet中的一些问题记录,portlet:resourceURL用法,portlet中通过processAction方法传值
在portlet页面中引入js或者css,通过c或者s标签 <!--jquery实际放的地方:/MyTask/WebContent/scripts/jquery-1.8.3.min.js--&g ...
- 移动端调用电话、短信、唤起QQ和使用百度地图
H5能很方便地实现这些功能,都是一句代码搞定 调用电话 <a href="tel:12345678"> 短信 <a href='sms:12345678'> ...
- Easyui datalist 使用记录
仅简单记录下,资料相对比较少 官方给了一个很简单的例子,没啥用处,文档:http://www.jeasyui.com/documentation/datalist.php 学习要点: 1.追加行 $( ...