【问题标题】:SQL query to get Groups and sub groups hierarchy获取组和子组层次结构的 SQL 查询
【发布时间】:2015-04-13 11:00:15
【问题描述】:

帐户表

ac_id       ac_name        st_id
----------- -------------  -----------
1           LIABILITES     1
2           ASSET          1
3           REVENUE        1
4           EXPENSES       1
5           EQUITY         1

组表

grp_id      grp_name            ac_no      grp_of     st_id   type_     cmp_id
----------- ------------------- ---------- -------- --------- --------- --------
1           Capital Account     1          0        1         0         0
2           Current Liability   1          0        1         0         0
3           Loan Liability      1          0        1         0         0
4           Suspense A/C        1          0        1         0         0
5           Current Assets      2          0        1         0         0
6           Fixed Assests       2          0        1         0         0
7           Investment          2          0        1         0         0
8           Misc. Expenses      2          0        1         0         0
9           Direct Income       3          0        1         0         0
10          Indirect Income     3          0        1         0         0
11          Sale Account        3          0        1         0         0
12          Direct Expense      4          0        1         0         0
13          Indirect Expense    4          0        1         0         0
14          Purchase Account    4          0        1         0         0
15          Sundry Creditors    2          1        1         0         0
16          Sundry Debitors     5          1        1         0         0
17          Bank Account        5          1        1         0         0
18          Cash In Hand        5          1        1         0         0
19          Duties & Taxes      2          1        1         0         0
20          Salary              12         1        1         0         0
21          Personal            5          1        1         0         0
22          Loan                2          0        1         0         0
23          Customer            16         1        1         0         0
34          Vendor              15         1        1         0         0
38          Sale Softwares      11         1        1         1         1
46          Stock In Hand       5          1        1         1         1
47          test                1          1        1         1         1
48          test in             47         1        1         1         1

查询以获取所有组层次结构。

declare @ac_no as int =2

;With CTE(grp_id,grp_name,ac_no,Level)
AS
(   SELECT 
        grp_id,grp_name,ac_no,CAST(1 AS int)
    FROM 
        Groups
    WHERE 
        grp_id in (select grp_id from Groups where (ac_no=@ac_no) and grp_of=0)
    UNION ALL
    SELECT 
        o.grp_id,o.grp_name,o.ac_no,c.Level+1
    FROM 
        Groups o
    INNER JOIN 
        CTE c 
        ON c.grp_id=o.ac_no --where o.ac_no=2 and o.grp_of=1
 )
select * from CTE

ac_no=2/3/4 的结果正常

grp_id      grp_name            ac_no       Level
----------- ------------------- ----------- ------
5           Current Assets      2           1
6           Fixed Assests       2           1
7           Investment          2           1
8           Misc. Expenses      2           1
22          Loan                2           1
16          Sundry Debitors     5           2
17          Bank Account        5           2
18          Cash In Hand        5           2
21          Personal            5           2
46          Stock In Hand       5           2
23          Customer            16          3

但是当我尝试获取ac_no=1 的结果时; 我得到错误:

消息 530,第 16 级,状态 1,第 4 行 声明终止。在语句完成之前,最大递归 100 已用完。

【问题讨论】:

标签: sql-server sql-server-2008 common-table-expression


【解决方案1】:

我认为问题在于你最终会陷入无限递归,因为你有一行是它自己的父/子(例如 grp_id = ac_no)。

我认为如果您像这样向递归成员添加限制子句,它应该可以工作:

DECLARE @ac_no AS int = 1;

WITH CTE (grp_id , grp_name , ac_no , Level ) AS ( 

    SELECT grp_id, grp_name, ac_no, CAST( 1 AS int )
    FROM Groups
    WHERE grp_id IN (SELECT grp_id FROM Groups WHERE ac_no = @ac_no AND grp_of = 0)

    UNION ALL

    SELECT o.grp_id, o.grp_name, o.ac_no, c.Level + 1
    FROM Groups o 
    INNER JOIN CTE c ON c.grp_id = o.ac_no --where o.ac_no=2 and o.grp_of=1
    WHERE c.ac_no <> c.grp_id 
    )

SELECT * FROM CTE;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    相关资源
    最近更新 更多