Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
platí pro:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analytics Platform System (PDW)
databáze SQL v Microsoft Fabric
Společný výraz tabulky (CTE) poskytuje významnou výhodu schopnosti odkazovat sám na sebe, a tím vytváří rekurzivní CTE. Rekurzivní CTE je ten, ve kterém se opakovaně spouští počáteční CTE, aby vracela podmnožiny dat, dokud se nezískala úplná sada výsledků.
Dotaz se označuje jako rekurzivní dotaz, když odkazuje na rekurzivní CTE. Návrat hierarchických dat je běžným využitím rekurzivních dotazů. Například zobrazení zaměstnanců v organizačním diagramu nebo data ve scénáři faktury k materiálům, ve kterém má nadřazený produkt jednu nebo více součástí a tyto komponenty můžou mít dílčí součásti nebo můžou být součástí jiných rodičů.
Rekurzivní CTE může výrazně zjednodušit kód potřebný ke spuštění rekurzivního dotazu v rámci příkazu SELECT, , INSERT, UPDATEDELETEnebo CREATE VIEW příkazu. V dřívějších verzích SQL Serveru rekurzivní dotaz obvykle vyžaduje použití dočasných tabulek, kurzorů a logiky k řízení toku rekurzivních kroků. Další informace o běžných výrazech tabulky najdete v tématu WITH common_table_expression.
V Microsoft Fabric, Fabric Data Warehouse a koncovém bodu SQL Analytics podporují standardní, sekvenční i vnořené cte, ale ne rekurzivní CTE.
Struktura rekurzivního CTE
Struktura rekurzivního CTE v Transact-SQL se podobá rekurzivním rutinám v jiných programovacích jazycích. I když rekurzivní rutina v jiných jazycích vrací skalární hodnotu, rekurzivní CTE může vrátit více řádků.
Rekurzivní CTE se skládá ze tří prvků:
Vyvolání rutiny.
První vyvolání rekurzivního CTE se skládá z jedné nebo více definic dotazů CTE spojených operátory
UNION ALL,UNION,EXCEPTneboINTERSECToperátory. Vzhledem k tomu, že tyto definice dotazů tvoří základní sadu výsledků struktury CTE, označují se jako členy ukotvení.Definice dotazů CTE se považují za ukotvené členy, pokud se na samotné CTE nedají odkazovat. Všechny definice dotazu členů ukotvení musí být umístěny před první rekurzivní definici členu a
UNION ALLoperátor musí být použit pro spojení posledního členu ukotvení s prvním rekurzivním členem.Rekurzivní vyvolání rutiny.
Rekurzivní vyvolání zahrnuje jednu nebo více definic dotazů CTE spojených operátory
UNION ALL, které odkazují na samotný CTE. Tyto definice dotazů se označují jako rekurzivní členy.Kontrola ukončení.
Kontrola ukončení je implicitní; rekurze se zastaví, pokud se z předchozího vyvolání nevrátí žádné řádky.
Note
Nesprávně složený rekurzivní CTE může způsobit nekonečnou smyčku. Pokud například definice rekurzivního dotazu člena vrátí stejné hodnoty pro nadřazené i podřízené sloupce, vytvoří se nekonečná smyčka. Při testování výsledků rekurzivního dotazu můžete omezit počet úrovní rekurze povolených pro konkrétní příkaz pomocí MAXRECURSION nápovědy a hodnoty mezi 0 a 32 767 v OPTION klauzuli , INSERTUPDATE, DELETEnebo SELECT příkazu.
Další informace najdete tady:
Pseudokód a sémantika
Rekurzivní struktura CTE musí obsahovat alespoň jeden člen ukotvení a jeden rekurzivní člen. Následující pseudokód ukazuje komponenty jednoduché rekurzivní CTE, která obsahuje jeden člen ukotvení a jeden rekurzivní člen.
WITH cte_name ( column_name [ ,...n ] )
AS
(
CTE_query_definition -- Anchor member is defined.
UNION ALL
CTE_query_definition -- Recursive member is defined referencing cte_name.
)
-- Statement using the CTE
SELECT *
FROM cte_name
Sémantika rekurzivního provádění je následující:
- Rozdělte výraz CTE na ukotvení a rekurzivní členy.
- Spusťte členy ukotvení, které vytvoří první vyvolání nebo základní sadu výsledků (
T0). - Spusťte rekurzivní členy
Tijako vstup aTi+ 1 jako výstup. - Opakujte krok 3, dokud se nevrátí prázdná sada.
- Vrátí sadu výsledků. To je o
UNION ALLT0tom, žeTn.
Examples
Následující příklad ukazuje sémantiku rekurzivní struktury CTE vrácením hierarchického seznamu zaměstnanců počínaje nejvyšším zaměstnancem v AdventureWorks2025 databázi. Návod ke spuštění kódu následuje v příkladu.
Vytvoření tabulky zaměstnanců:
CREATE TABLE dbo.MyEmployees
(
EmployeeID SMALLINT NOT NULL,
FirstName NVARCHAR (30) NOT NULL,
LastName NVARCHAR (40) NOT NULL,
Title NVARCHAR (50) NOT NULL,
DeptID SMALLINT NOT NULL,
ManagerID INT NULL,
CONSTRAINT PK_EmployeeID PRIMARY KEY CLUSTERED (EmployeeID ASC)
);
Naplňte tabulku hodnotami:
INSERT INTO dbo.MyEmployees
VALUES
(1, N'Ken', N'Sánchez', N'Chief Executive Officer', 16, NULL),
(273, N'Brian', N'Welcker', N'Vice President of Sales', 3, 1),
(274, N'Stephen', N'Jiang', N'North American Sales Manager', 3, 273),
(275, N'Michael', N'Blythe', N'Sales Representative', 3, 274),
(276, N'Linda', N'Mitchell', N'Sales Representative', 3, 274),
(285, N'Syed', N'Abbas', N'Pacific Sales Manager', 3, 273),
(286, N'Lynn', N'Tsoflias', N'Sales Representative', 3, 285),
(16, N'David', N'Bradley', N'Marketing Manager', 4, 273),
(23, N'Mary', N'Gibson', N'Marketing Specialist', 4, 16);
USE AdventureWorks2008R2;
GO
WITH DirectReports (ManagerID, EmployeeID, Title, DeptID, Level)
AS (
-- Anchor member definition
SELECT e.ManagerID,
e.EmployeeID,
e.Title,
edh.DepartmentID,
0 AS Level
FROM dbo.MyEmployees AS e
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.EmployeeID = edh.BusinessEntityID
AND edh.EndDate IS NULL
WHERE ManagerID IS NULL
UNION ALL
-- Recursive member definition
SELECT e.ManagerID,
e.EmployeeID,
e.Title,
edh.DepartmentID,
Level + 1
FROM dbo.MyEmployees AS e
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.EmployeeID = edh.BusinessEntityID
AND edh.EndDate IS NULL
INNER JOIN DirectReports AS d
ON e.ManagerID = d.EmployeeID)
-- Statement that executes the CTE
SELECT ManagerID,
EmployeeID,
Title,
DeptID,
Level
FROM DirectReports
INNER JOIN HumanResources.Department AS dp
ON DirectReports.DeptID = dp.DepartmentID
WHERE dp.GroupName = N'Sales and Marketing'
OR Level = 0;
GO
Názorný postup ukázky kódu
Rekurzivní CTE DirectReportsdefinuje jeden člen ukotvení a jeden rekurzivní člen.
Člen ukotvení vrátí základní sadu T0výsledků . Toto je nejvyšší hodnocení zaměstnanců ve společnosti. To znamená, že zaměstnanec, který nehlásí manažerovi.
Tady je sada výsledků vrácená členem ukotvení:
ManagerID EmployeeID Title Level
--------- ---------- ----------------------------- ------
NULL 1 Chief Executive Officer 0
Rekurzivní člen vrátí přímé podřízené zaměstnance v sadě výsledků členů ukotvení. Toho dosáhnete operací spojení mezi tabulkou Zaměstnanec a DirectReports CTE. Jedná se o odkaz na samotný CTE, který stanoví rekurzivní vyvolání. Na základě zaměstnance v CTE DirectReports jako vstup (Ti), spojení (MyEmployees.ManagerID = DirectReports.EmployeeID) vrátí jako výstup (Ti + 1), zaměstnanci, kteří mají (Ti) jako svého nadřízený .
Proto první iterace rekurzivního členu vrátí tuto sadu výsledků:
ManagerID EmployeeID Title Level
--------- ---------- ----------------------------- ------
1 273 Vice President of Sales 1
Rekurzivní člen je aktivován opakovaně. Druhá iterace rekurzivního členu jako vstupní hodnotu používá sadu výsledků s jedním řádkem v kroku 3 (obsahující hodnotu EmployeeID273) a vrátí tuto sadu výsledků:
ManagerID EmployeeID Title Level
--------- ---------- ----------------------------- ------
273 16 Marketing Manager 2
273 274 North American Sales Manager 2
273 285 Pacific Sales Manager 2
Třetí iterace rekurzivního členu používá jako vstupní hodnotu předchozí sadu výsledků a vrátí tuto sadu výsledků:
ManagerID EmployeeID Title Level
--------- ---------- ----------------------------- ------
16 23 Marketing Specialist 3
274 275 Sales Representative 3
274 276 Sales Representative 3
285 286 Sales Representative 3
Konečná sada výsledků vrácená spuštěným dotazem je sjednocení všech sad výsledků vygenerovaných ukotvením a rekurzivními členy.
Tady je soubor výsledků.
ManagerID EmployeeID Title Level
--------- ---------- ----------------------------- ------
NULL 1 Chief Executive Officer 0
1 273 Vice President of Sales 1
273 16 Marketing Manager 2
273 274 North American Sales Manager 2
273 285 Pacific Sales Manager 2
16 23 Marketing Specialist 3
274 275 Sales Representative 3
274 276 Sales Representative 3
285 286 Sales Representative 3
Související obsah
- WITH common_table_expression (Transact-SQL)
- Rady dotazů (Transact-SQL)
- INSERT (Transact-SQL)
- AKTUALIZACE (Transact-SQL)
- DELETE (Transact-SQL)
- KROMĚ A INTERSECT (Transact-SQL)
- Rekurzivní CTE