很多时候,我们做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自己的子集,即可。

最新文章

  1. JavaScript 实现彩票中随机数组的获取
  2. C++(MFC)中WebBrowser去除3D边框的方法(实现IDocHostUIHandler接口)控制 WebBrowser 控件的外观和行为
  3. C++ 记事本: 变量
  4. BusyBox Init
  5. acdream 1685 多民族王国(DFS,并查集)
  6. [转]用Python做一个自动生成读表代码的小脚本
  7. js中对闭包的理解
  8. nodejs广播
  9. Ext JS学习第五天 Ext_window组件(一)
  10. Cygwin-添加到右键菜单脚本--一键安装、卸载
  11. 页面跳转之session
  12. 爬虫应对js混淆的方法
  13. AQS实现原理分析——ReentrantLock
  14. 字符串replaceAll()方法报错:java.util.regex.PatternSyntaxException:Unclosed group near index...
  15. web(三)html标签
  16. 一个完整的Installshield安装程序实例-转
  17. Codeforces 535C - Tavas and Karafs
  18. iOS开发小技巧--富文本字典集合中的Key都是OC中的常量字符串
  19. java中集合去重2
  20. ubuntu下root不能复制 abc用户下的软连接文件

热门文章

  1. Codeforces 777E:Hanoi Factory(贪心)
  2. Chapter 21 G-Methods for Time-Varying Treatments
  3. WEB文档在线预览解决方案
  4. Java初学者作业——实现控制台的猜数字游戏。游戏运行时产生一个1~100之间的随机数字
  5. 在页面中添加两个 <select> 标签,用来显示年份和月份;同时添加两个 <ul> 标签,一个用来显示星期,另一个用来显示日期 在 JavaScript 脚本中动态添加年份和月份,获取当前日期的年份
  6. 解决windows update失败,正在还原的问题
  7. Python+flask+flask-apscheduer实现定时下发任务
  8. Python_关于python2的encode(编码)和decode(解码)的使用
  9. Django_模板中的URL参数化(四)
  10. 在git上下载的源码项目,运行时报错AssertionError [ERR_ASSERTION] [ERR_ASSERTION]: Task function must be specified