例子一

-- =============================================
-- 根据EID返回其下属的EID,Layer=1表示直接下属,NULL返回所有下属
-- select EID FROM F_Team_GetSubordinate(2,NULL)
-- =============================================
CREATE FUNCTION F_Team_GetSubordinate(
@EID INT,
@Layer INT)
RETURNS @tb TABLE (EID INT,NameCN varchar(50),SupervisorEID INT,Layer INT)
AS
BEGIN ;WITH CTE AS
(
SELECT EID,NameCn,SupervisorEID,0 as Layer FROM TCFG_Employee WHERE EID=@EID
UNION ALL
SELECT A.EID,A.NameCn,A.SupervisorEID,Layer=layer+1 FROM TCFG_Employee A
JOIN CTE B ON A.SupervisorEID = B.EID
) INSERT INTO @tb
select EID,NameCN,SupervisorEID,Layer from CTE where (@Layer IS NULL OR Layer=@Layer) return
END GO

例子二

--[员工]表含成层级关系
CREATE TABLE Employees (
empid INT NOT NULL,
mgrid INT NULL,--管理者ID字段,用于链接empid
empname VARCHAR (25) NOT NULL,
salary money NOT NULL,
CONSTRAINT PK_Employees PRIMARY KEY (empid),
)
GO -- 插入实例数据,允许员工的管理者ID字段为null,
INSERT INTO Employees VALUES(1, NULL, 'Nancy', $10000.00)
INSERT INTO Employees VALUES(2, 1, 'Andrew', $5000.00)
INSERT INTO Employees VALUES(3, 1, 'Janet', $5000.00)
INSERT INTO Employees VALUES(4, 1, 'Margaret',$5000.00)
INSERT INTO Employees VALUES(5, 2, 'Steven', $2500.00)
INSERT INTO Employees VALUES(6, 2, 'Michael', $2500.00)
INSERT INTO Employees VALUES(7, 3, 'Robert', $2500.00)
INSERT INTO Employees VALUES(8, 3, 'Laura', $2500.00)
INSERT INTO Employees VALUES(9, 3, 'Ann', $2500.00)
INSERT INTO Employees VALUES(10, 4, 'Ina', $2500.00)
INSERT INTO Employees VALUES(11, 7, 'David', $2000.00)
INSERT INTO Employees VALUES(12, 7, 'Ron', $2000.00)
INSERT INTO Employees VALUES(13, 7, 'Dan', $2000.00)
INSERT INTO Employees VALUES(14, 11, 'James', $1500.00)
GO --Create Departments table and insert demo values
CREATE TABLE Departments (
deptid INT NOT NULL PRIMARY KEY,
deptname VARCHAR (25) NOT NULL,
deptmgrid INT NULL REFERENCES Employees --部门管理者ID,外键参考Employees的empid字段
)
GO INSERT INTO Departments VALUES (1, 'HR', 2)
INSERT INTO Departments VALUES (2, 'Marketing', 7)
INSERT INTO Departments VALUES (3, 'Finance', 8)
INSERT INTO Departments VALUES (4, 'R&D', 9)
INSERT INTO Departments VALUES (5, 'Training', 4)
INSERT INTO Departments VALUES (6, 'Gardening', NULL)
GO
-- 这个自定义函数根据用工ID,返回他所有的下属(包括下属的下属,即所有层)
CREATE FUNCTION dbo.fn_getsubtree(@empid AS INT) RETURNS @TREE TABLE
(
empid INT NOT NULL,
empname VARCHAR(25) NOT NULL,
mgrid INT NULL,
lvl INT NOT NULL
)
AS
BEGIN
WITH Employees_Subtree(empid, empname, mgrid, lvl) AS --lvl层级字段
(
-- Anchor Member (AM)
SELECT empid, empname, mgrid, 0
FROM employees
WHERE empid = @empid --这个查询输出将作为下个查询的输入!
-- 下属,即那些管理者字段的值等于自己的Employee字段
UNION all
-- Recursive Member (RM)
SELECT e.empid, e.empname, e.mgrid, es.lvl+1
FROM employees AS e
JOIN employees_subtree AS es --employees_subtree是WITH后面的变量名,相当于JOIN自己链接自己
ON e.mgrid = es.empid
)
INSERT INTO @TREE
SELECT * FROM Employees_Subtree
RETURN
END
GO -- Call for show
SELECT * FROM fn_getsubtree(1) --通过这个例子理解CROSS APPLY 说明:表Departments和自定义函数fn_getsubtree链接
--查询每个部门管理者他们包含(所有层次)的下属,特别说明,返回的结果集的记录存在部分记录字段重复
--因为fn_getsubtree是返回所有层次的下属,所以下面的查询也返回每个部门下所有层次的下属
SELECT *
FROM Departments AS D
CROSS APPLY fn_getsubtree(D.deptmgrid) AS ST --deptmgrid 部门的领导id

例子三

WITH T AS
(
SELECT empid, empname, mgrid,0 AS Lv FROM Employees
UNION ALL
SELECT e.empid, e.empname, e.mgrid,es.Lv+1 FROM Employees AS e --不支持*号!字段名必须一一写出来,并且和上面的SELECT一模一样!
JOIN T AS es --链接自己啊
ON e.mgrid = es.empid
)
SELECT * FROM T 已经在好多场合看到这些的写法了,所有觉得比较重要.
===========================
用例数表
CREATE TABLE Employees (
empid INT NOT NULL,
mgrid INT NULL,--管理者字段,是自链接字段!
empname VARCHAR (25) NOT NULL,
salary money NOT NULL,
CONSTRAINT PK_Employees PRIMARY KEY (empid),
)
GO -- 允许员工的部门为null,
INSERT INTO Employees VALUES(1, NULL, 'Nancy', $10000.00)
INSERT INTO Employees VALUES(2, 1, 'Andrew', $5000.00)
INSERT INTO Employees VALUES(3, 1, 'Janet', $5000.00)
INSERT INTO Employees VALUES(4, 1, 'Margaret',$5000.00)
INSERT INTO Employees VALUES(5, 2, 'Steven', $2500.00)
INSERT INTO Employees VALUES(6, 2, 'Michael', $2500.00)
INSERT INTO Employees VALUES(7, 3, 'Robert', $2500.00)
INSERT INTO Employees VALUES(8, 3, 'Laura', $2500.00)
INSERT INTO Employees VALUES(9, 3, 'Ann', $2500.00)
INSERT INTO Employees VALUES(10, 4, 'Ina', $2500.00)
INSERT INTO Employees VALUES(11, 7, 'David', $2000.00)
INSERT INTO Employees VALUES(12, 7, 'Ron', $2000.00)
INSERT INTO Employees VALUES(13, 7, 'Dan', $2000.00)
INSERT INTO Employees VALUES(14, 11, 'James', $1500.00)
GO
=========================

SQL Server递归实例的更多相关文章

  1. SQL Server 多实例下的复制

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 搭建步骤(Procedure) 注意事项(Attention) 二.背景(Contexts) ...

  2. SQL Server的实例恢复解析

    同Oracle一样,SQL Server在非一致性关闭的时候也会进行实例恢复(Instance Recovery),本文根据stack overflow的文章介绍一些SQL Server实例恢复的知识 ...

  3. 当SQL Server的实例位于集群的特定节点时,数据库无法远程访问

    搭建好了一个集群环境,发现当SQL Server的实例位于集群的其中一个节点时,数据库无法远程访问,报如下错误.但在另一个 节点时,数据库访问正常. 标题: 连接到服务器 -------------- ...

  4. Step7:SQL Server 多实例下的复制

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 搭建步骤(Procedure) 注意事项(Attention) 二.背景(Contexts) ...

  5. SQL Server数据库实例名与服务器名不一致的解决办法

    SQL Server数据库实例名与服务器名不一致的解决办法 --EXEC sp_addlinkedserver --   @server = 'PSHGQ' --GO --select * from  ...

  6. SQL Server 命名实例更改端口进行发布订阅

    原文:SQL Server 命名实例更改端口进行发布订阅 两台数据库服务器,都没有加入域,都安装多实例,端口也不一样了.现在使用命名实例进行复制,折腾了好久,才发现解决方法. 服务器A:myserve ...

  7. 【故障公告】阿里云 RDS SQL Server 数据库实例 CPU 100% 引发全站故障

    非常抱歉,今天 8:48 开始,我们使用的阿里云 RDS SQL Server 数据库实例突然出现 CPU 100%  问题,引发全站故障,由此给您带来麻烦,请您谅解. 发现故障后立即进行主备切换,和 ...

  8. 查看SQL Server多实例的版本

    通过 select @@version 查看当前的 SQL Server 安装的版本: 结果返回的是 SQL Server 2008 R2 (SP1),可安装的明明是 SQL Server 2012  ...

  9. 迁移SQL SERVER 数据库实例

    由于某些原因,需要将2个数据库实例合并为1个,也就是说要把其中的一台迁移到另外一台上面. 背景介绍 :下面的B,C代表2个实例,要把B中相关东西迁移到C实例上面.其中B上面有一部分的同步是从另外一台服 ...

随机推荐

  1. 「小程序JAVA实战」小程序导航组件(26)

    转自:https://idig8.com/2018/08/19/xiaochengxujavashizhanxiaochengxudaohangzujian26/ 来说下 ,小程序的导航组件.源码:h ...

  2. 太白老师day6 1.代码块 2.is==id 3.小数据池

    1.代码块: 一个模块一个函数一个类,一个文件都是代码块 在交互模式下, 每一行都是一个代码块 2. is == 内存地址 就是id门牌号 在内存中id是唯一,如果两个变量指向的id相同,那么他们在内 ...

  3. Android真机调试手动添加程序包的LogCat

    android真机调试有时候看LogCat 时,有时候那个跑的本程序的LogCat 没有出现而是 出现的是" All messages (no filters) " .此时 的Lo ...

  4. Python基础学习八 写日志

    import logging from logging import handlers class Logger(object): level_relations = { 'debug': loggi ...

  5. shell 中可以for 循环的时间加减日期格式

    ..};do # LAST_HOUR=`date -d '-${num} hour' +%H` 不可for循环,报格式错误 LAST_HOUR=`date "+%H" -d -${ ...

  6. PHP - 用户异常断开连接,脚本强制继续执行,异常退出回调

    试想如下情况.如果你的用户正在执行一个需要非常长的执行时间的操作.他点了执行了之后,浏览器就开始蛋疼地转.如果执行5分钟,你猜他会干啥,显然会觉得什么狗屎垃圾站,这么久都不响应,然后就给关了.当然这个 ...

  7. android游戏的增量更新(资源及代码的热更新)

    需求当游戏需要更新时,不必让用户下载新的完整包,只需要通过游戏内部的更新系统自动更新差异包,达到节约用户流量和时间的目的. 大体思路:1.(游戏逻辑用lua等脚本编写的情况)这种方式的增量更新非常简单 ...

  8. R包安装失败failed to download mirrors file

    在R console中使用install.packages()来安装第三方包时,会出现这样的错误: 即使我们选择的是China的镜像也解决不了问题. 这时候,可以先试试用IE打开上图中黑底部分的URL ...

  9. 利用Fiddler对Android模拟器网络请求进行抓包

    安装使用Fiddler 下载安装Fiddler的方法这里就略过了,一路Next就行了.装好之后运行软件,正常情况这个时候我们已经可以对电脑的网络请求进行抓包了.Fiddler默认的代理地址是127.0 ...

  10. iOS导航栏自由缩放头像效果

    效果图: 上代码: 先给一个self.navigationItem.titleView ,然后再放个ImangeView添加到titleView上: UIView *titleView = [[UIV ...