等价于Microsoft MSSQL中具有递归功能的Postgres?

时间:2018-08-24 07:43:50

标签: sql-server common-table-expression

我有一个使用Postgres(9.4)数据库的现有WebApp。 该应用程序具有相当标准的权限结构,其中用户属于组,并且组织中的级别/部门属于层次结构(级别具有父级)。

DataModel的相关部分是:

create table level(level_id int primary key, parent_level int);
create table grouplevel(level_id int, group_id int);
create table usergroup(user_id int, group_id int);

该应用程序使用Postgres的WITH RECURSIVE功能遍历“级别”树,以收集用户具有“组”权限的level_id分层列表。换句话说,它首先列出了顶级级别,然后列出了他们的子级,以及子级的子级

SELECT
level_id
FROM
(
    WITH RECURSIVE tree(level_id, root)AS(
        SELECT
            C .level_id,
            C .parent_level
        FROM
            LEVEL C
        LEFT JOIN LEVEL P ON C .level_id = P .parent_level
        WHERE
            P .level_id IN(
                SELECT
                    GL.level_id
                FROM
                    GROUPLEVEL GL
                JOIN USERGROUP UG ON(GL.GROUP_ID = UG.GROUP_ID)
                WHERE
                    USER_ID = 1
            )
        UNION
            SELECT
                tree.level_id,
                root
            FROM
                tree
            INNER JOIN LEVEL ON tree.root = LEVEL .level_id
    )SELECT
        *
    FROM
        tree
)AS T
UNION
(
    SELECT
        GL.level_id
    FROM
        GROUPLEVEL GL
    JOIN USERGROUP UG ON(GL.GROUP_ID = UG.GROUP_ID)
    WHERE
        USER_ID = 1
)

现在我们正在使用MSSQL后端实现该应用程序-是否有任何方法可以在MSSQL中实现相同类型的递归/层次结构列表?

1 个答案:

答案 0 :(得分:0)

内部查询可以重构为:

 ;WITH   tree(level_id, root)AS(
        SELECT
            C .level_id, C .parent_level
        FROM
            LEVEL C
        LEFT JOIN LEVEL P ON C .level_id = P .parent_level
        WHERE
            P .level_id IN(
                SELECT
                    GL.level_id
                FROM
                    GROUPLEVEL GL
                JOIN USERGROUP UG ON(GL.GROUP_ID = UG.GROUP_ID)
                WHERE
                    USER_ID = 1
            )
        UNION all SELECT tree.level_id, root FROM tree
            INNER JOIN LEVEL ON tree.root = LEVEL .level_id
    )SELECT * FROM tree

但是我还没有找到将其包含在内部查询中的方法