sql server 公共表达式(CTE)的简单应用

  现在做项目数据访问基本都会选择一种orm框架,它以面向对象的形式屏蔽底层的数据访问形式,让开发人员更集中在业务处理上,而不是和数据库的交互上,帮助我们提高开发效率;例如一些简单的insert、update,我们不需要写insert into...sql 语句,而是直接new一个实体对象,然后db.Insert(entity),看起来是那么清爽;像EF这样比较完善的orm,支持linq语法对数据库进行访问,写起来就更加爽了,有些人甚至认为开发人员可以不用会写sql语句了...但现实不会让你工作得那么轻松,作为开发人员对数据库这一块的学习还是很有必要的;且不说一些灵活性和效率问题,实际工作中用sql的地方还是非常多的,经常在码代码的时候,突然就传来领导的声音,那个某某某,你赶紧给我出一份报表,那个谁谁谁,你赶紧给我出一份XXX的数据...很急。

  最近在码代码时,领导就来一句:嘿man,你给我统计一下所有xxx产品的信息,要快,那边在催了...。这里抽象一下,如下,大概就是找出所有家具产品的信息,这个分类表包含树形结构,ParentId为0是某种分类的根,它下面可能有许多种子节点/叶子节点。这里需要要找的实际就是一个以家具为根的树。

  

测试sql语句:

DECLARE @Product TABLE
(ProductId INT,
 ParentId INT,
 ProductName NVARCHAR(64))

INSERT INTO @Product
VALUES
(1,0,‘家具‘),
(2,0,‘服装‘),
(3,1,‘大型家具‘),
(4,1,‘小型家具‘),
(5,2,‘男装‘),
(6,2,‘女装‘),
(7,3,‘床‘),
(8,3,‘衣柜‘),
(9,3,‘沙发‘),
(10,4,‘电脑桌‘),
(11,4,‘椅子‘),
(12,5,‘牛仔裤‘),
(13,5,‘衬衫‘),
(14,6,‘裙子‘)

  这种需求实际很多,有经验的朋友很快就知道怎么写,而实际写法也很简单。知道这是树形结构,在脑海里出现了:自链接查询、子查询、临时表、游标、用程序写代码递归...公共表达式(CTE),OK!CTE的语法如下:

WITH CTE名称[目标列]
AS
(
<定义CTE的内部查询>
)
<对CTE进行查询的外部查询>

  具体来说,CTE属于表表达式,另一种表表达式是派生表(子查询),有时候使用CTE可以优化我们的代码,使我们的代码更加简单、易读。而且CTE支持递归查询,上面的需求写法为:

;WITH cte
AS
(SELECT * FROM @Product
  WHERE ProductId = 1
 UNION ALL
 SELECT p.* FROM @Product p
  INNER JOIN cte t ON p.ParentId = t.ProductId
)
SELECT*FROM cte
 ORDER BY ProductId

  CTE的递归查询主要包含两个部分,定位点成员和递归成员。如上面的查询,UNION ALL 前面的SELECT 就是定位点成员,它是查询的初始化;UNION ALL下面的属于递归成员,我们可以递归查询时,每次都为CTE返回上一次的结果集。例如,初始化时,cte结果是ProductId 1,第一次递归时,会找到ParentId为1的产品,也就是3,4,并且与上一个结果集UNION ALL得到本次结果集返回,再递归时cte就是1,3,4了;而递归的结束条件就是本次查询的结果为空集,此时递归结束,并返回最终结果集。

  另外需要说的是,CTE是虚拟的,sql server会为它重新生成查询语句,直接访问底层对象;所以在一些性能要求较高的地方,还是要通过执行计划来判断是否需要优化,有时候方便是以性能为代价的。

时间: 2024-10-25 08:36:30

sql server 公共表达式(CTE)的简单应用的相关文章

SQL Server中的锁的简单学习

原文:SQL Server中的锁的简单学习 简介 在SQL Server中,每一个查询都会找到最短路径实现自己的目标.如果数据库只接受一个连接一次只执行一个查询.那么查询当然是要多快好省的完成工作.但对于大多数数据库来说是需要同时处理多个查询的.这些查询并不会像绅士那样排队等待执行,而是会找最短的路径执行.因此,就像十字路口需要一个红绿灯那样,SQL Server也需要一个红绿灯来告诉查询:什么时候走,什么时候不可以走.这个红绿灯就是锁. 图1.查询可不会像绅士们那样按照次序进行排队 为什么需要

sql server中的cte

从SQL Server 2005开始,提供了CTE(Common Table Expression,公用表表达式)的语法支持. CTE是定义在SELECT.INSERT.UPDATE或DELETE语句中的临时命名的结果集,同时CTE也可以用在视图的定义中. 在CTE中可以包括对自身的引用,因此这种表达式也被称为递归CTE. CTE的优点 公用表表达式提供的功能其实和视图差不多,但是它不像视图一样把SQL语句保存在我们的数据库里面. 微软官方给出的使用CTE的优势: 1.可以编写一个递归查询. 2

Sql server 表表达式

1.表表达式概述 (1)表表达式(table expression) 是一个命名的查询表达式.代表一个有效的关系表 (2)在DML 中,使用表表达式和使用其他表非常类似 (3)sqlserver 支持4种表表达式: 派生表.公用表达式(CTE).视图 .内嵌值函数(内嵌TVF) (4)表表达式没有任何的物理实例化.是虚拟的.内部查询是嵌套 的 (5)使用表表达式的好处是代码逻辑方便有关.与性能无关.表表达式本身不会对性能带来正负影响 2.有效定义表表达式查询需要满足的3个要求 2.1 无法保证顺

SQL Server -&gt;&gt; Revert表达式

Revert表达式从SQL Server 2005就有.它的作用是用于切换当前过程的执行上下文返回上一个EXECUTE AS 语句发生之前的安全上下文.Revert可以在存储过程.ad-hoc环境下.用户定义函数中使用.Revert是需要和EXECUTE AS配合使用. 这里引用一个MSDN的例子 -- Create two temporary principals. CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb'; CREATE LOGIN l

【转】SQL SERVER标量表达式的隐式转换

在SQL Server中的数据类型中,存在着优先级的问题.标量表达示的返回结果类型也会根据操作数的类型而定,如1 +'1'=2.而不是'11',因些Int型的优先级比VARCHAR型的优先级要高.所以在表达示的结果隐式转换成Int型. 同样对于标量函数,如一个表的一列是Int型,表中有两行值为2和3如果对这一列使用AVG函数,则结果是2,而不是2.5.但是如果这一列是Decimal类型的话,那么结果就是2.5.因为结果类型依据操作数据类型. 如下的一个Case语名 CASE WHEN <logi

SQL Server Profiler查询跟踪的简单使用

1.打开SQL Server Management Studio,选择工具->SQL Server Profiler,或者直接从路径:开始/程序/Microsoft SQL Server 2008 R2 /性能工具/SQL Server Profiler. 2.连接数据库后,直接打开跟踪新增界面,或者在路径:文件->新建跟踪下新增跟踪,连接数据库 3.点击事件选择页,选择事件,将需要显示的列打上勾,这样才会在跟踪的时候,显示出这些列: 4.只看当前用户需要查看的数据库,这就用到列筛选器功能,点

C# 操作SQL Server 公共库

基本够用,存一下,以后找起来方便 public abstract class DB { //数据库连接字符串(config来配置) protected static string connectionString = ConfigurationManager.AppSettings["connectionString"]; public DB() { } #region 公用方法 public static int GetMaxID(string FieldName, string T

SQL Server关于存储过程的一点简单使用心得

===========================创建无参无返回值的存储过程===========================create proc pro_nameas--要执行的sql语句--select * from tablename --执行存储过程--exec pro_name ===========================创建有参无返回值的存储过程===========================--带参存储过程create proc proc_find_stu

SQL Server 公共分页存储过程及使用方法

-- 使用方法:在获取查询列表的存储过程中执行,并指定参数就行了-- exec ListPage @SQL, @PageSize, @PageNo, @OrderStr, @OrderType-- @SQL   查询语句-- @PageSize 数据数量-- @PageNo  当前页码-- @OrderStr 排序字段-- @OrderType 排序 0 ASC 1 DESCUSE [DataBaseName]--数据库名称GOSET ANSI_NULLS ONGOSET QUOTED_IDEN