SQL递归层次结构

时间:2016-09-27 10:45:25

标签: sql sql-server recursion

我正在努力让一个递归的CTE按预期工作,但仍然没有机会.. 所以,我有以下类似的表结构:

tblMapping

map_id  | type_id  | name  | parent_id
1         1          A1      0
2         1          A2      0
3         1          A3      1
4         1          A4      3
5         2          B1      0
6         2          B2      5
7         2          B3      6
8         1          A5      4
9         2          B4      0

tblRoleGroup

role_group_id  | type_id  | map_id  | desc_id
1                1          0         null
1                2          0         null
2                1          3         1
2                2          6         0
3                1          8         1
3                2          9         1 

在tblRoleGroup中,desc_id字段表示:

null - allow all (used only in combination with map_id=0)
0    - allow all from parent including parent
1    - allow only current node

如果map_id=0仍在tblRoleGroup中,那么查询应该从同一个type_id获取所有元素

查询结果应如下所示:

role_group_id  | type_id  | map_id  | path
1                1          1         A1
1                1          2         A2
1                1          3         A1.A3
1                1          4         A1.A3.A4
1                1          8         A1.A3.A4.A5
1                2          5         B1
1                2          6         B1.B2
1                2          7         B1.B2.B3
1                2          9         B4
2                1          3         A1.A3
2                2          6         B1.B2
2                2          7         B1.B2.B3
3                1          8         A1.A3.A4.A5
3                2          9         B4

下面的查询只解决了预期结果的一部分,但我无法使其按预期结果运行。

WITH Hierarchy(map_id, type_id, name, Path) AS 
    (
    SELECT t.map_id, t.type_id, t.name, CAST(t.name AS varchar(MAX)) AS Expr1
        FROM dbo.tblMapping AS t 
            LEFT JOIN dbo.tblMapping AS t1 ON t1.map_id = t.parent_id
        WHERE (t1.parent_id=0)  
    UNION ALL   
    SELECT t.map_id, t.type_id, t.name, CAST(h.Path + '.' + t.name AS varchar(MAX)) AS Expr1
        FROM Hierarchy AS h 
            JOIN dbo.tblMapping AS t ON t.parent_id = h.map_id
    )
SELECT h.map_id, h.type_id, t.role_group_id, h.Path AS Path
    FROM Hierarchy AS h
    LEFT JOIN dbo.tblRoleGroup t ON t.map_id = h.map_id    

有人可以帮我这个吗? 谢谢

1 个答案:

答案 0 :(得分:1)

首先,我创建了一个函数,它带来了传递<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <select class="mySelectBox"> <option value="1">option1</option> <option value="2">option2</option> <option value="3">option3</option> <option value="4">option4</option> <option value="5">option5</option> </select> <input type="checkbox" name="box1"> <input type="checkbox" name="box2"> <input type="checkbox" name="box3"> <input type="checkbox" name="box4"> <input type="checkbox" name="box5">的所有后代:

map_id

然后运行:

CREATE FUNCTION mapping (@map_id int)  
RETURNS TABLE  
AS  
RETURN   
(  
    WITH rec AS (
    SELECT  map_id, 
            [type_id], 
            CAST(name as nvarchar(max)) as name, 
            parent_id
    FROM tblMapping
    WHERE map_id = @map_id
    UNION ALL
    SELECT  m.map_id,
            m.[type_id],
            r.name+'.'+m.name,
            m.parent_id
    FROM rec r
    INNER JOIN tblMapping m
    ON m.parent_id = r.map_id
    )

    SELECT *
    FROM rec
);  
GO  

会给你:

;WITH rec AS (
SELECT  map_id, 
        [type_id], 
        CAST(name as nvarchar(max)) as name, 
        parent_id
FROM tblMapping
WHERE parent_id=0
UNION ALL
SELECT  m.map_id,
        m.[type_id],
        r.name+'.'+m.name,
        m.parent_id
FROM rec r
INNER JOIN tblMapping m
ON m.parent_id = r.map_id
)


SELECT  t.role_group_id,
        r.[type_id],
        r.map_id,
        r.name as [path]
FROM tblRoleGroup t 
CROSS JOIN rec r
WHERE r.[type_id] = CASE WHEN t.desc_id IS NULL AND t.map_id = 0 THEN t.[type_id] ELSE NULL END
   OR r.map_id = CASE WHEN t.desc_id = 1 THEN t.map_id ELSE NULL END
   OR r.map_id IN (
                    SELECT map_id
                    FROM dbo.mapping (CASE WHEN t.desc_id = 0 THEN t.map_id ELSE NULL END)
                    )
ORDER BY role_group_id, r.[type_id], r.map_id