zoukankan      html  css  js  c++  java
  • 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自己的子集,即可。

  • 相关阅读:
    IM设计思考:XMPP多用户文本聊天协议(MUC:Multi User Chat)
    软件设计中的“三视图”
    [C++] 应该如何应对OOM?
    Android 上Camera分析
    android的语言切换应用程序 根据 不同的语言 加载不同的 res
    布局
    布局
    如何解决"Launching New_configuration"问题
    android的语言切换应用程序 根据 不同的语言 加载不同的 res
    如何解决"Launching New_configuration"问题
  • 原文地址:https://www.cnblogs.com/LearningC/p/8142797.html
Copyright © 2011-2022 走看看