Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use SQL CTE table to include path and all children

I have following hierarchical tree table

GO
DROP TABLE #tbl 
GO
CREATE TABLE #tbl (Id int , ParentId int)
INSERT  INTO #tbl (Id, ParentId) VALUES  (0, NULL)
INSERT  INTO #tbl (Id, ParentId) VALUES  (1, 0)
INSERT  INTO #tbl (Id, ParentId) VALUES  (2, 1)
INSERT  INTO #tbl (Id, ParentId) VALUES  (3, 1)
INSERT  INTO #tbl (Id, ParentId) VALUES  (4, 2)
INSERT  INTO #tbl (Id, ParentId) VALUES  (5, 2)
INSERT  INTO #tbl (Id, ParentId) VALUES  (6, 3)
INSERT  INTO #tbl (Id, ParentId) VALUES  (7, 3)
GO

Which maps to following tree

0
+- 1
   +- 2
      +- 4
      +- 5
   +- 3
      +- 6
      +- 7

Using CTE Recursive table, how can I get the path and also all children of the selected node. For example having 2 as input, how can I get following data (ordered if possible)

Id, ParentID
-------
 0, NULL 
 1, 0
 2, 1
 4, 2
 5, 2

I know I can traverse up in the tree (get path) with following statement

WITH RecursiveTree AS (
    -- Anchor
    SELECT *
        FROM #tbl
        WHERE Id = 2
    UNION ALL
        -- Recursive Member
        SELECT Parent.*
        FROM 
            #tbl AS Parent
            JOIN RecursiveTree AS Child ON Child.ParentId = Parent.Id
)
SELECT * FROM RecursiveTree

And with following statement, traverse down in the tree (get all children)

WITH RecursiveTree AS (
    -- Anchor
    SELECT *
        FROM #tbl
        WHERE Id = 2
    UNION ALL
        -- Recursive Member
        SELECT Child.*
        FROM 
            #tbl AS Child
            JOIN RecursiveTree AS Parent ON Child.ParentId = Parent.id
)
SELECT * FROM RecursiveTree

Question: How to combine these two commands into one?

like image 733
AaA Avatar asked Feb 13 '13 08:02

AaA


People also ask

Can a CTE be used for multiple queries?

Unlike a derived table, a CTE behaves more like an in-line view and can be referenced multiple times in the same query. Using a CTE makes complex queries easier to read and maintain. Because a CTE can be referred to multiple times in a query, syntax can be simpler.

What are the disadvantages of using CTE in SQL Server?

Disadvantages of CTECTE's members cannot use the following clauses of keywords Distinct, Group By, Having, Top, Joins limiting by this type of the queries that can be created and reducing their complexity. The Recursive member can refer to the CTE only once.

Can we use where clause in CTE?

As others mentioned, it just depends on the query. Moving the WHERE clause outside vs inside of a CTE can alter the execution plan and result in drastically different performance. I'm seen it happen numerous times. But in simple queries, generally it'll make no difference.

What is CTE in SQL with example?

A common table expression, or CTE, is a temporary named result set created from a simple SELECT statement that can be used in a subsequent SELECT statement. Each SQL CTE is like a named query, whose result is stored in a virtual table (a CTE) to be referenced later in the main query.


1 Answers

Just use UNION of these two selects

SQLFiddle demo

WITH RecursiveTree AS (
    -- Anchor
    SELECT *
        FROM #tbl
        WHERE Id = 2
    UNION ALL
        -- Recursive Member
        SELECT Parent.*
        FROM 
            #tbl AS Parent
            JOIN RecursiveTree AS Child ON Child.ParentId = Parent.Id
),
RecursiveTree2 AS
(
    -- Anchor
    SELECT *
        FROM #tbl
        WHERE Id = 2
    UNION ALL
        -- Recursive Member
        SELECT Child.*
        FROM 
            #tbl AS Child
            JOIN RecursiveTree2 AS Parent ON Child.ParentId = Parent.id
)
select * from
(
SELECT * FROM RecursiveTree
union
SELECT * FROM RecursiveTree2
) t
order by id
like image 193
valex Avatar answered Jan 03 '23 13:01

valex