SQL 中进行递归
阅读原文时间:2023年07月10日阅读:1

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

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章