很多时候,我们做Tree的时候会用到递归。但是一般都是从数据库中拿到数据然后再程序中进行递归。昨天一个巧合,一位同事给我看了数据库中的递归,乍一看还不太明白。

表结构是这样的

CREATE TABLE [dbo].[WA_Menu](
[MenuID] [int] IDENTITY(1,1) NOT NULL,
[MenuName] [nvarchar](20) NULL,
[MenuCode] [nvarchar](32) NULL,
[MenuUrl] [nvarchar](100) NULL,
[MenuIcon] [nvarchar](20) NULL,
[MenuParentID] [int] NULLPRIMARY KEY CLUSTERED
(
[MenuID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

以上隐去了部分字段。

SQL是这样的:

WITH SUB AS(
SELECT * FROM WA_Menu WHERE MenuID = 1
UNION ALL
SELECT A.* FROM WA_MENU A INNER JOIN SUB ON SUB.MenuID = A.MenuParentID
)
SELECT * FROM SUB

是不是比程序中的代码简单,直接返回我要的子集,根据MenuID 得到它所有的子集。

后来百度了一下 WITH AS 的语法(CTE语法),他可以让你定义一段SQL供其他的SQL语句使用。定义部分也是可以的。

如果有多个CTE语句,我们用 分号隔开。如:

WITH A AS
(
-- DO SOMETHING
), B AS
(
-- DO SOMETHING
)
此时,在 A中可以使用A B中可以使用 A B ,最后紧接着的SQL ,一定要使用 CTE引用。

如下面的就不对:
WITH A AS
(
-- DO SOMETHING
), B AS
(
-- DO SOMETHING
)
SELECT * FROM D

因为 D和 A B 子查询没有任何关系,正确的写法应该是:

WITH A AS
(
-- DO SOMETHING
), B AS
(
-- DO SOMETHING
)
SELECT * FROM A INNER JOIN B ON A.ID =B.ID

如果想要递归,只需要在 CTE表达式中union自己的子集,即可。

SQL 中进行递归的更多相关文章

  1. java.sql.SQLException: ORA-00604: 递归 SQL 级别 1 出现错误

    后台报出如下错误: Caused by: java.sql.SQLException: ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01000: 超出打开游标的最大数 ORA-00 ...

  2. SQL With(递归 CTE 查询)

    本文来自:http://www.cnblogs.com/smailxiaobai/archive/2012/01/16/2323291.html 指定临时命名的结果集,这些结果集称为公用表表达式 (C ...

  3. SQL中常见语句

    SQL中常见语句笔记: --替换字段中的回车符和换行符 ) ), '') --删除表命令 DROP TABLE [dbo].[MGoods_Test] --删除表中数据命令 DELETE FROM [ ...

  4. SQL中Round(),Floor(),Ceiling()函数的浅析

    项目中的一个功能模块上用到了标量值函数,函数中又有ceiling()函数的用法,自己找了一些资料,对SQL中这几个函数做一个简单的记录,方便自己学习.有不足之处欢迎拍砖补充 1.round()函数遵循 ...

  5. 关于sql中in 和 exists 的效率问题,in真的效率低吗

    原文: http://www.cnblogs.com/AdamLee/p/5054674.html 在网上看到很多关于sql中使用in效率低的问题,于是自己做了测试来验证是否是众人说的那样. 群众: ...

  6. 学习sql中的排列组合,在园子里搜着看于是。。。

    学习sql中的排列组合,在园子里搜着看,看到篇文章,于是自己(新手)用了最最原始的sql去写出来: --需求----B, C, F, M and S住在一座房子的不同楼层.--B 不住顶层.C 不住底 ...

  7. SQL中distinct的用法

    SQL中distinct的用法   1.作用于单列 2.作用于多列 3.COUNT统计 4.distinct必须放在开头 5.其他 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出 ...

  8. hibernate中java类的成员变量类型如何映射到SQL中的数据类型变化

    hibernate映射文件??.hbm.xml配置映射元素详解--Hibernate映射类型 在从Hibernate的java的成员类型映射到SQL中的数据类型,其内映射方式它满足,SQL可以自己调制 ...

  9. C#调用SQL中的存储过程中有output参数,存储过程执行过程中返回信息

      C#调用SQL中的存储过程中有output参数,类型是字符型的时候一定要指定参数的长度.不然获取到的结果总是只有第一字符.本人就是由于这个原因,折腾了很久.在此记录一下,供大家以后参考! 例如: ...

随机推荐

  1. window11连接局域网共享失败处理办法

    第一步1.按 Win + R 组合键,打开运行,并输入:gpedit.msc 命令,确定或回车,可以快速打开本地组策略编辑器2.本地组策略编辑器窗口中,依次展开到:计算机配置 - 管理模板 - 网络 ...

  2. Docker 与 K8S学习笔记(十)—— 容器的端口映射

    我们一般将应用部署在容器里面,而一个服务器上会有许许多多的容器,那么外界该如何访问我们的应用呢?答案是:端口映射. Docker可以将容器对外提供服务的端口映射到host的某个端口上,外网通过此端口访 ...

  3. 洛谷 P3431:[POI2005]AUT-The Bus(离散化+DP+树状数组)

    题目描述 The streets of Byte City form a regular, chessboardlike network - they are either north-south o ...

  4. Java GUI 桌面应用开发

    前言 虽然现在已经很少项目会涉及GUI技术,但作为一个合格的Java开发工程师,还是得了解才得 本文记录,idea使用JFormDesigner插件进行Java GUI 桌面应用开发 GUI Swin ...

  5. Generative Adversarial Nets (GAN)

    目录 目标 框架 理论 数值实验 代码 Generative Adversarial Nets 这篇文章,引领了对抗学习的思想,更加可贵的是其中的理论证明,证明很少却直击要害. 目标 GAN,译名生成 ...

  6. 解决vue生产环境app.js或vendor文件过大问题

    1.去掉多余的库 将不必要的库卸载掉 npm uninstall xxx 举个例子:例如moment库文件是很大的,在前端可以用js的 new Date实现获取日期,或者可以其他库代替,也可以将mom ...

  7. Java链式调用

    疯狂的类构造器Builder模式,链式调用 以swagger配置类为例 比如需要返回一个ApiInfo 的类,可以直接new一个ApiInfo,这样一般需要把参数都填上 或者,可以使用他的builde ...

  8. 【优雅代码】07-spring下的优秀工具类

    [优雅代码]07-spring下的优秀工具类 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有帮助到你的话请顺手点 ...

  9. centos 目录结构

    bin -----存放命令的目录(bin目录是快捷方式)是/usr/bin的快捷方式 sbin ----只有root用户才能使用的命令 etc ----系统服务的配置文件 /usr/local --- ...

  10. linux服务器之间传输文件的四种方式

    linux文件传输在内网渗透中至关重要,所以我在此总结一下几种Linux服务器之间传输文件的四种方式 1. scp [优点]简单方便,安全可靠:支持限速参数[缺点]不支持排除目录[用法]scp就是se ...