Question

I need help understanding the recursive portion of this query:

WITH EmpsCTE AS
(
    SELECT empid, mgrid, firstname, lastname
    FROM HR.Employees
    WHERE empid = 2

    UNION ALL

    SELECT C.empid, C.mgrid, C.firstname, C.lastname
    FROM EmpsCTE AS P
        JOIN HR.Employees AS C
            ON C.mgrid = P.empid
)

SELECT empid, mgrid, firstname, lastname
FROM EmpsCTE;

Result of the query above is shown below.

enter image description here

Here is a picture of the HR.employees table.

enter image description here

(Click for enlarged version)

I am unable to understand WHY the code is recursing. I understand how the table outputs all employees where the direct manager is the manager with the empid of 2, but I don't understand why the code recurses and produces the subordinates of the employees UNDER empid 2.

Was it helpful?

Solution

Recursive queries using CTE like the one above usually consist of two parts within the definition of CTE. The first one gets the record(s) that you will start recursion from (anchor records)

SELECT empid, mgrid, firstname, lastname
FROM HR.Employees
WHERE empid = 2

This will select your top-most employee.

Then to achieve recursion you need to UNION with the second part of the CTE query (to get recursive records):

UNION ALL

SELECT C.empid, C.mgrid, C.firstname, C.lastname
FROM EmpsCTE AS P
    JOIN HR.Employees AS C
        ON C.mgrid = P.empid

The most important points here are:

  • you need to join the alias used in CTE definition (EmpsCTE) with the source table (HR.Employees). This will produce recursion as it will join the records already existing in CTE with the records from the source table. This will be done until the invocation of the recurive part returns no records.
  • as your join condition links an employee to its manager, the recursive part will continue to produce records as long as there are new employees that work under those who the query already returned in previous iterations.

Let me also paste a section from enter link description here on that topic to explain it in the official way:

The structure of the recursive CTE in Transact-SQL is similar to recursive routines in other programming languages. Although a recursive routine in other languages returns a scalar value, a recursive CTE can return multiple rows.

A recursive CTE consists of three elements:

  • Invocation of the routine.

The first invocation of the recursive CTE consists of one or more CTE_query_definitions joined by UNION ALL, UNION, EXCEPT, or INTERSECT operators. Because these query definitions form the base result set of the CTE structure, they are referred to as anchor members. CTE_query_definitions are considered anchor members unless they reference the CTE itself. All anchor-member query definitions must be positioned before the first recursive member definition, and a UNION ALL operator must be used to join the last anchor member with the first recursive member.

  • Recursive invocation of the routine.

The recursive invocation includes one or more CTE_query_definitions joined by UNION ALL operators that reference the CTE itself. These query definitions are referred to as recursive members.

  • Termination check.

The termination check is implicit; recursion stops when no rows are returned from the previous invocation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top