Geht das… cycle … (rekursive Abfragen)


Apache DerbyBigQueryDb2 (LUW)H2MariaDBMySQLOracle DBPostgreSQLSQL ServerSQLite200520072009201120132015201720192021⊘ 3.5.7 - 3.41.0⊘ 2008R2 - 2022✓ 14+⊘ 8.3 - 13⚠ 11gR2 - 21ca⊘ 11gR1⊘ 5.0 - 8.0.32⚠ 10.5 - 10.11ab⊘ 5.1 - 10.4⊘ 1.4.191 - 2.1.214⊘ 9.7 - 11.5.8⊘ 2.0⊘ 10.15.1.3 - 10.16.1.1
  1. Keine using … Sub-Klausel
  2. Verwende cycle … restrict

Die Cycle-Klausel überwacht ausgewählte Spalten des Ergebnisses einer rekursive Anfrage auf wiederkehrende Werte. Wenn dieselben Werte ein zweies mal aufscheinen, verhindert die Cycle-Klausel, dass dieser Pfad ein zweites Mal verfolgt wird. Damit verhindert die Cycle-Klausel Endlosschleifen.

WITH RECURSIVE path (a, b) AS (
  SELECT edges.* FROM edges
                WHERE a = 1
UNION ALL
  SELECT edges.* FROM edges
                 JOIN path 
                   ON edges.a = path.b
)
CYCLE a
  SET cycl TO 'Y' DEFAULT 'N'
USING path_array
SELECT *
  FROM path
 WHERE cycl = 'N'

Beachte, dass das Ergebnis jeweils eine Zeile pro geschlossener Schleife doppelt beinhaltet. Die in der Set-Unterklausel definierte Spalte cycl kann zum Entfernen dieser Dupplikate verwendet werden.

Die Cycle-Klausel besteht aus drei Teilen:

CYCLE <Spaltenliste>

Liste der Spalten, bei denen eine Schleife – und nur eine Schleife – zu wiederkehrenden Werten führt.

SET <column name> [TO <value> DEFAULT <value>]

Fügt eine Spalte hinzu, welche jene Zeilen markiert, die eine Schleife geschlossen haben.

Die optionalen To- und Default-Unterklauseln legen fest welchen Wert Zeile erhalten, bevor eine Schleife geschlossen wurde (to) und welche die Schleife geschossen haben (default). Wenn diese Klauseln nicht angegeben werden, wird to false default true verwendet.0

USING <column name>

Fügt eine Spalte hinzu, welche den Weg, der zu jeder Zeile geführt hat, in einem Array protokolliert.

Die Werte des Arrays sind Zeilenwerte der Spalten die unmittelbar hinter dem Schlüsselwort cycle angegeben wurden.

Obwohl der SQL-Standard die Set- und Using-Unterklauseln verbindlich vorschreibt, sind sie konzeptionell nicht notwendig, wenn man die entsprechenden Spalten im Ergebnis nicht braucht. Manche Produkte unterstützen diese Klauseln überhaupt nicht. Beachte jedoch, dass das weglassen der Set-Klausel eine logische Konsequenz hat: Jene Zeilen, die ein Schleife gescholossen haben und im Ergebnis doppelt aufscheinen, können dann nicht mehr wie im Beispiel gezeit mit einer Where-Klausel entfernt wrden. Daher führt das Weglassen der Set-Klausel bei manchen Produkten auch dazu, dass Duplikate generell nicht ausgegeben werden.

Normative Referenzen

Die Cycle-Klausel ist in ISO/IEC 9075:2016-2 als Teil des optionalen Features T131, „Recursive query“ definiert.

Über den Autor

Foto von Markus Winand

Markus Winand ist der SQL Renaissance Botschafter auf der Mission, Entwickler auf die Evolution von SQL im 21. Jahrhundert aufmerksam zu machen. Markus kann als Trainer, Sprecher und Berater auf winand.at engagiert werden.

Sein Buch kaufen

Titelbild von „SQL Performance Explained“: Eichhörnchen läuft durchs Grass

Die Essenz: SQL-Tuning auf 200 Seiten

Jetzt Kaufen
(Taschenbuch und/oder PDF)

Sein Training

Markus verwandelt veraltetes SQL-92-Wissen in solides und zeitgemäßes SQL-Know-how

Erfahren Sie mehr»

Fußnoten

  1. Die To- und Default-Klauseln akzeptieren nur Werte von den Typen char(1) und boolean.

Mit Markus Winand verbinden

Markus Winand auf LinkedInMarkus Winand auf XINGMarkus Winand auf Twitter
„modern SQL“ von Markus Winand ist unter einer Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License lizenziert.
Impressum | Kontakt | KEINE GEWÄHR | Handelsmarken | Datenschutz und DSGVO | CC-BY-NC-ND 3.0 Lizenz