Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL Server CTE und Rekursionsbeispiel

Ich habe Ihren Code nicht getestet, sondern nur versucht, Ihnen zu helfen, zu verstehen, wie er in Kommentaren funktioniert;

WITH
  cteReports (EmpID, FirstName, LastName, MgrID, EmpLevel)
  AS
  (
-->>>>>>>>>>Block 1>>>>>>>>>>>>>>>>>
-- In a rCTE, this block is called an [Anchor]
-- The query finds all root nodes as described by WHERE ManagerID IS NULL
    SELECT EmployeeID, FirstName, LastName, ManagerID, 1
    FROM Employees
    WHERE ManagerID IS NULL
-->>>>>>>>>>Block 1>>>>>>>>>>>>>>>>>
    UNION ALL
-->>>>>>>>>>Block 2>>>>>>>>>>>>>>>>>    
-- This is the recursive expression of the rCTE
-- On the first "execution" it will query data in [Employees],
-- relative to the [Anchor] above.
-- This will produce a resultset, we will call it R{1} and it is JOINed to [Employees]
-- as defined by the hierarchy
-- Subsequent "executions" of this block will reference R{n-1}
    SELECT e.EmployeeID, e.FirstName, e.LastName, e.ManagerID,
      r.EmpLevel + 1
    FROM Employees e
      INNER JOIN cteReports r
        ON e.ManagerID = r.EmpID
-->>>>>>>>>>Block 2>>>>>>>>>>>>>>>>>
  )
SELECT
  FirstName + ' ' + LastName AS FullName,
  EmpLevel,
  (SELECT FirstName + ' ' + LastName FROM Employees
    WHERE EmployeeID = cteReports.MgrID) AS Manager
FROM cteReports
ORDER BY EmpLevel, MgrID

Das einfachste Beispiel eines rekursiven CTE Ich kann mir vorstellen, um seine Funktionsweise zu veranschaulichen:

;WITH Numbers AS
(
    SELECT n = 1
    UNION ALL
    SELECT n + 1
    FROM Numbers
    WHERE n+1 <= 10
)
SELECT n
FROM Numbers

F 1) wie der Wert von N erhöht wird. wenn der Wert jedes Mal N zugewiesen wird, dann kann der N-Wert erhöht werden, aber nur das erste Mal, wenn der N-Wert initialisiert wurde .

A1: In diesem Fall N ist keine Variable. N ist ein Pseudonym. Es ist das Äquivalent zu SELECT 1 AS N . Es ist eine Syntax der persönlichen Präferenz. Es gibt zwei Hauptmethoden zum Aliasing von Spalten in einem CTE in T-SQL . Ich habe das Analogon eines einfachen CTE eingefügt in Excel um zu versuchen, auf vertrautere Weise zu veranschaulichen, was passiert.

--  Outside
;WITH CTE (MyColName) AS
(
    SELECT 1
)
-- Inside
;WITH CTE AS
(
    SELECT 1 AS MyColName
    -- Or
    SELECT MyColName = 1  
    -- Etc...
)

F 2) jetzt hier über CTE und Rekursion der Mitarbeiterbeziehung, sobald ich zwei Manager hinzufüge und einige weitere Mitarbeiter unter dem zweiten Manager hinzufüge, dann beginnt das Problem. Ich möchte die Details des ersten Managers anzeigen und in den nächsten Zeilen werden nur diese Mitarbeiterdetails angezeigt diejenigen, die diesem Manager unterstellt sind

A2:

Beantwortet dieser Code Ihre Frage?

--------------------------------------------
-- Synthesise table with non-recursive CTE
--------------------------------------------
;WITH Employee (ID, Name, MgrID) AS 
(
    SELECT 1,      'Keith',      NULL   UNION ALL
    SELECT 2,      'Josh',       1      UNION ALL
    SELECT 3,      'Robin',      1      UNION ALL
    SELECT 4,      'Raja',       2      UNION ALL
    SELECT 5,      'Tridip',     NULL   UNION ALL
    SELECT 6,      'Arijit',     5      UNION ALL
    SELECT 7,      'Amit',       5      UNION ALL
    SELECT 8,      'Dev',        6   
)
--------------------------------------------
-- Recursive CTE - Chained to the above CTE
--------------------------------------------
,Hierarchy AS
(
    --  Anchor
    SELECT   ID
            ,Name
            ,MgrID
            ,nLevel = 1
            ,Family = ROW_NUMBER() OVER (ORDER BY Name)
    FROM Employee
    WHERE MgrID IS NULL

    UNION ALL
    --  Recursive query
    SELECT   E.ID
            ,E.Name
            ,E.MgrID
            ,H.nLevel+1
            ,Family
    FROM Employee   E
    JOIN Hierarchy  H ON E.MgrID = H.ID
)
SELECT *
FROM Hierarchy
ORDER BY Family, nLevel

Noch eine SQL mit Baumstruktur

SELECT ID,space(nLevel+
                    (CASE WHEN nLevel > 1 THEN nLevel ELSE 0 END)
                )+Name
FROM Hierarchy
ORDER BY Family, nLevel