Domanda

i have the following table

ID   CATALOGUE  SWID   PARENTSWID   LEVEL
1       1         1         1         0
2       1         2         1         1
3       1         3         1         1 
4       1         4         2         2
5       1         5         4         3
6       1         6         5         4
7       2         2         2         0
8       2         3         2         1

So I want all elements (SWID) which have the PARENTSWID= "1".

The root level is always "0", and root element have the same SWID and PARENTSWID

There are no boundaries for the depth of the tree. Later I will have to restrict the search with the CATALOGUE property, but for now I need an idea how to set this up.

So, has somebody done anything like this ? :)

Kind regards Semir


WITH cte as
(
SELECT ID, CATALOGUE, SWID, PARENTSWID, LEVEL
FROM table
WHERE PARENTSWID = 1
AND LEVEL = 0
UNION ALL
SELECT t.ID, t.CATALOGUE, t.SWID, t.PARENTSWID, t.LEVEL
FROM table t
JOIN CTE ON cte.ID = t.PARENTSWID
AND t.LEVEL= cte.LEVEL+1
)
SELECT ID, CATALOGUE, SWID, PARENTSWID, LEVEL FROM cte;

when trying this i get the error "unknown ISC error 336397226".
I have looked up this error and it means : 336397226 dsql_cte_cycle CTE '@1' has cyclic dependencies

My table has the same items as the one here

(I have tried it on IBWSQL with my DB selected)

È stato utile?

Soluzione 2

Here is my solution for Firebird SQL using Common Table Expressions.

CREATE TABLE STACKOVERFLOW0001 (
    ID          INTEGER,
    CATALOUGE   INTEGER,
    SWID        INTEGER,
    PARENTSWID  INTEGER,
    "LEVEL"     INTEGER
);

INSERT INTO STACKOVERFLOW0001 (ID, CATALOUGE, SWID, PARENTSWID, "LEVEL")
                       VALUES (1, 1, 1, 1, 0);
INSERT INTO STACKOVERFLOW0001 (ID, CATALOUGE, SWID, PARENTSWID, "LEVEL")
                       VALUES (2, 1, 2, 1, 1);
INSERT INTO STACKOVERFLOW0001 (ID, CATALOUGE, SWID, PARENTSWID, "LEVEL")
                       VALUES (3, 1, 3, 1, 1);
INSERT INTO STACKOVERFLOW0001 (ID, CATALOUGE, SWID, PARENTSWID, "LEVEL")
                       VALUES (4, 1, 4, 2, 2);
INSERT INTO STACKOVERFLOW0001 (ID, CATALOUGE, SWID, PARENTSWID, "LEVEL")
                       VALUES (5, 1, 5, 4, 3);
INSERT INTO STACKOVERFLOW0001 (ID, CATALOUGE, SWID, PARENTSWID, "LEVEL")
                       VALUES (6, 1, 6, 5, 4);
INSERT INTO STACKOVERFLOW0001 (ID, CATALOUGE, SWID, PARENTSWID, "LEVEL")
                       VALUES (7, 2, 2, 2, 0);
INSERT INTO STACKOVERFLOW0001 (ID, CATALOUGE, SWID, PARENTSWID, "LEVEL")
                       VALUES (8, 2, 3, 2, 1);

COMMIT WORK;

Query 

WITH RECURSIVE cat (id,catalouge,swid,parentswid,lvl)
as
(
    select id,catalouge,swid,parentswid,"LEVEL" from stackoverflow0001 as r
    where r."LEVEL" = 0 -- Magic Happens here for Filtering, you can specify the Start of the recursive tree walk down from here.


    union all

    select r.id, r.catalouge, r.swid, r.parentswid,r."LEVEL" from stackoverflow0001 as r,cat
    where cat.swid = r.parentswid -- This is what matches up the first query record to the child records
    and r."LEVEL" > 0 -- Just an additional filter check for child records.
)

select * from cat
// You can also stick some where clauses here if you need

Output

ID  CATALOUGE   SWID    PARENTSWID  LVL
1   1   1   1   0
2   1   2   1   1
4   1   4   2   2
5   1   5   4   3
6   1   6   5   4
8   2   3   2   1
3   1   3   1   1
7   2   2   2   0
4   1   4   2   2
5   1   5   4   3
6   1   6   5   4
8   2   3   2   1
8   2   3   2   1

Altri suggerimenti

This works with sqlserver 2005+

DECLARE @PARENTSWID int = 1
;WITH cte as
(
SELECT ID, CATALOGUE, SWID, PARENTSWID, LEVEL
FROM table
WHERE PARENTSWID = @PARENTSWID
AND LEVEL = 0
UNION ALL
SELECT t.ID, t.CATALOGUE, t.SWID, t.PARENTSWID, t.LEVEL
FROM table t
JOIN CTE ON cte.ID = t.PARENTSWID
AND t.LEVEL = cte.LEVEL +1
)
SELECT ID, CATALOGUE, SWID, PARENTSWID, LEVEL FROM cte
OPTION (MAXRECURSION 0)

See this fiddle.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top