SQL 中進行遞歸


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM