SHORTEST_PATH (Transact-SQL)
Gilt für: SQL Server 2019 (15.x) und höhere Versionen Azure SQL-Datenbank Azure SQL verwaltete Instanz SQL-Datenbank in Microsoft Fabric
Gibt eine Suchbedingung für ein Diagramm an, das rekursiv oder wiederholt durchsucht wird. SHORTEST_PATH können in MATCH mit Graphknoten und Randtabellen in der SELECT-Anweisung verwendet werden.
Transact-SQL-Syntaxkonventionen
Kürzester Pfad
Mit der SHORTEST_PATH-Funktion können Sie Folgendes finden:
- Ein kürzester Pfad zwischen zwei bestimmten Knoten/Entitäten
- Kürzester Pfad(n) mit einer quelle.
- Kürzester Pfad von mehreren Quellknoten zu mehreren Zielknoten.
Es akzeptiert ein beliebiges Längenmuster als Eingabe und gibt einen kürzesten Pfad zurück, der zwischen zwei Knoten vorhanden ist. Diese Funktion kann nur innerhalb von VERGLEICH verwendet werden. Die Funktion gibt nur einen kürzesten Pfad zwischen zwei bestimmten Knoten zurück. Wenn es zwei oder mehr kürzeste Pfade derselben Länge zwischen einem beliebigen Quell- und Zielknotenpaar gibt, gibt die Funktion nur einen Pfad zurück, der beim Durchlaufen zuerst gefunden wurde. Ein beliebiges Längenmuster kann nur innerhalb einer SHORTEST_PATH-Funktion angegeben werden.
Eine vollständige Syntax finden Sie unter VERGLEICH (SQL Graph).For complete syntax, refer to MATCH (SQL Graph).
FÜR PFAD
FOR PATH muss mit einem beliebigen Knoten- oder Randtabellennamen in der FROM-Klausel verwendet werden, der an einem beliebigen Längenmuster teilnimmt. FOR PATH teilt dem Modul mit, dass die Knoten- oder Randtabelle eine sortierte Auflistung zurückgibt, die die Liste der Knoten oder Kanten darstellt, die entlang des durchlaufenen Pfads gefunden wurden. Die Attribute aus diesen Tabellen können nicht direkt in der SELECT-Klausel projiziert werden. Um Attribute aus diesen Tabellen zu projizieren, müssen Aggregatfunktionen für Diagrammpfade verwendet werden.
Beliebiges Längenmuster
Dieses Muster enthält die Knoten und Kanten, die wiederholt durchlaufen werden müssen, bis:
- Der gewünschte Knoten ist erreicht.
- Die maximale Anzahl von Iterationen, wie im Muster angegeben, ist erfüllt.
Die folgenden beiden Muster quantifizierer werden unterstützt:
- '+': Wiederholen Sie das Muster 1 oder mehr. Beenden, sobald der kürzeste Pfad gefunden wird.
- {1,n} : Das Muster 1 bis n Male wiederholen. Beenden Sie, sobald eine kürzeste gefunden wird.
LAST_NODE
LAST_NODE()-Funktion ermöglicht die Verkettung von zwei beliebigen Längen-Traversalmustern. Sie kann in Szenarien verwendet werden, in denen:
- In einer Abfrage werden mehrere kürzeste Pfadmuster verwendet, und ein Muster beginnt beim LETZTEN Knoten des vorherigen Musters.
- Zwei kürzeste Pfadmuster werden mit demselben LAST_NODE() zusammengeführt.
Diagrammpfadreihenfolge
Die Reihenfolge des Diagrammpfads bezieht sich auf die Reihenfolge der Daten im Ausgabepfad. Die Reihenfolge des Ausgabepfads beginnt immer am nichtcursiven Teil des Musters, gefolgt von den Knoten/Kanten, die im rekursiven Teil angezeigt werden. Die Reihenfolge, in der das Diagramm während der Abfrageoptimierung/-ausführung durchlaufen wird, hat nichts mit der Reihenfolge zu tun, die in der Ausgabe gedruckt wird. Ebenso wirkt sich die Richtung des Pfeils im rekursiven Muster nicht auf die Reihenfolge des Diagrammpfads aus.
Graph-Pfadaggregatfunktionen
Da die Knoten und Ränder, die an einem beliebigen Längenmuster beteiligt sind, eine Auflistung (von knoten(n) und Rändern zurückgeben, die in diesem Pfad durchlaufen werden), können Benutzer die Attribute nicht direkt mit der herkömmlichen Syntax "tablename.attributename" projizieren. Verwenden Sie für Abfragen, in denen Attributwerte aus den Zwischenknoten oder Randtabellen projiziert werden müssen, im durchlaufenen Pfad die folgenden Aggregatfunktionen des Diagrammpfads: STRING_AGG, LAST_VALUE, SUMME, AVG, MIN, MAX und ANZAHL. Die allgemeine Syntax für die Verwendung dieser Aggregatfunktionen in der SELECT-Klausel lautet:
<GRAPH_PATH_AGGREGATE_FUNCTION>(<expression> , <separator>) <order_clause>
<order_clause> ::=
{ WITHIN GROUP (GRAPH PATH) }
<GRAPH_PATH_AGGREGATE_FUNCTION> ::=
STRING_AGG
| LAST_VALUE
| SUM
| COUNT
| AVG
| MIN
| MAX
STRING_AGG
Die STRING_AGG-Funktion verwendet einen Ausdruck und ein Trennzeichen als Eingabe und gibt eine Zeichenfolge zurück. Benutzer können diese Funktion in der SELECT-Klausel verwenden, um Attribute aus den Zwischenknoten oder Rändern im durchlaufenen Pfad zu projizieren.
LAST_VALUE
Zum Projizieren von Attributen vom letzten Knoten des durchlaufenen Pfads können LAST_VALUE Aggregatfunktion verwendet werden. Fehler beim Bereitstellen des Randtabellenalias als Eingabe für diese Funktion, es können nur Knotentabellennamen oder Aliase verwendet werden.
Letzter Knoten: Der letzte Knoten bezieht sich auf den Knoten, der zuletzt im pfadverquerten Pfad angezeigt wird, unabhängig von der Pfeilrichtung im MATCH-Prädikat. Beispiel: MATCH(SHORTEST_PATH(n(-(e)->p)+) )
Hier ist der letzte Knoten im Pfad der zuletzt besuchte P-Knoten.
MATCH(SHORTEST_PATH((n<-(e)-)+p))
Im Muster ist der letzte Knoten der zuletzt besuchte N-Knoten.
SUM
Diese Funktion gibt die Summe der bereitgestellten Knoten-/Edge-Attributwerte oder ausdrücke zurück, die im durchlaufenen Pfad angezeigt wurden.
COUNT
Diese Funktion gibt die Anzahl der Nicht-NULL-Werte des angegebenen Knoten-/Edge-Attributs im Pfad zurück. Die FUNKTION ANZAHL unterstützt den *
Operator nicht – versuchte Verwendung von *
Ergebnissen in einem Syntaxfehler.
{ COUNT( <expression> ) <order_clause> }
DURCHSCHN.
Gibt den Mittelwert der bereitgestellten Knoten-/Edge-Attributwerte oder ausdrücke zurück, die im durchlaufenen Pfad angezeigt wurden.
MIN
Gibt den Minimalwert aus den bereitgestellten Knoten-/Edge-Attributwerten oder Ausdrücken zurück, die im durchlaufenen Pfad angezeigt wurden.
MAX
Gibt den maximalen Wert aus den bereitgestellten Knoten-/Edge-Attributwerten oder Ausdrücken zurück, die im durchlaufenen Pfad angezeigt wurden.
Hinweise
- Die SHORTEST_PATH-Funktion kann nur in MATCH verwendet werden.
- Die LAST_NODE-Funktion wird nur in SHORTEST_PATH unterstützt.
- Die SHORTEST_PATH-Funktion gibt einen kürzesten Pfad zwischen Knoten zurück. Es wird derzeit nicht unterstützt, alle kürzesten Pfade zwischen Knoten zurückzugeben. Außerdem wird das Zurückgeben aller Pfade zwischen Knoten nicht unterstützt.
- Die SHORTEST_PATH Implementierung findet einen ungewichteten, kürzesten Pfad.
- In einigen Fällen können schlechte Pläne für Abfragen mit einer höheren Anzahl von Hops generiert werden, was zu höheren Abfrageausführungszeiten führt. Bewerten Sie, ob Abfragehinweise wie OPTION (HASH JOIN) und / oder OPTION (MAXDOP 1) Hilfe.
Beispiele
Für die hier gezeigten Beispielabfragen verwenden wir die Knoten- und Randtabellen, die im SQL Graph-Beispiel erstellt wurden.
A. Suchen des kürzesten Pfads zwischen zwei Personen
Im folgenden Beispiel finden wir den kürzesten Pfad zwischen Jacob und Alice. Wir benötigen den Knoten und friendOf
den Edge, der Person
aus dem SQL Graph-Beispiel erstellt wurde.
SELECT PersonName, Friends
FROM (
SELECT
Person1.name AS PersonName,
STRING_AGG(Person2.name, '->') WITHIN GROUP (GRAPH PATH) AS Friends,
LAST_VALUE(Person2.name) WITHIN GROUP (GRAPH PATH) AS LastNode
FROM
Person AS Person1,
friendOf FOR PATH AS fo,
Person FOR PATH AS Person2
WHERE MATCH(SHORTEST_PATH(Person1(-(fo)->Person2)+))
AND Person1.name = 'Jacob'
) AS Q
WHERE Q.LastNode = 'Alice'
B. Suchen Sie den kürzesten Pfad von einem bestimmten Knoten zu allen anderen Knoten im Diagramm.
Im folgenden Beispiel werden alle Personen gefunden, mit denen Jakob im Diagramm verbunden ist, und den kürzesten Weg, der von Jacob zu all diesen Menschen beginnt.
SELECT
Person1.name AS PersonName,
STRING_AGG(Person2.name, '->') WITHIN GROUP (GRAPH PATH) AS Friends
FROM
Person AS Person1,
friendOf FOR PATH AS fo,
Person FOR PATH AS Person2
WHERE MATCH(SHORTEST_PATH(Person1(-(fo)->Person2)+))
AND Person1.name = 'Jacob'
C. Zählen Sie die Anzahl der Hops/Ebenen, die durchlaufen werden, um von einer Person zu einer anderen im Diagramm zu wechseln.
Das folgende Beispiel findet den kürzesten Pfad zwischen Jacob und Alice und druckt die Anzahl der Hops, die es benötigt, um von Jacob nach Alice zu gehen.
SELECT PersonName, Friends, levels
FROM (
SELECT
Person1.name AS PersonName,
STRING_AGG(Person2.name, '->') WITHIN GROUP (GRAPH PATH) AS Friends,
LAST_VALUE(Person2.name) WITHIN GROUP (GRAPH PATH) AS LastNode,
COUNT(Person2.name) WITHIN GROUP (GRAPH PATH) AS levels
FROM
Person AS Person1,
friendOf FOR PATH AS fo,
Person FOR PATH AS Person2
WHERE MATCH(SHORTEST_PATH(Person1(-(fo)->Person2)+))
AND Person1.name = 'Jacob'
) AS Q
WHERE Q.LastNode = 'Alice'
D: Suchen von Personen 1-3 Hops von einer bestimmten Person entfernt
Das folgende Beispiel findet den kürzesten Weg zwischen Jacob und allen Personen, mit denen Jacob in der Grafik verbunden ist, ein bis drei Hops von ihm entfernt.
SELECT
Person1.name AS PersonName,
STRING_AGG(Person2.name, '->') WITHIN GROUP (GRAPH PATH) AS Friends
FROM
Person AS Person1,
friendOf FOR PATH AS fo,
Person FOR PATH AS Person2
WHERE MATCH(SHORTEST_PATH(Person1(-(fo)->Person2){1,3}))
AND Person1.name = 'Jacob'
E. Suchen von Personen genau zwei Hops von einer bestimmten Person entfernt
Im folgenden Beispiel wird der kürzeste Weg zwischen Jacob und Personen gefunden, die genau zwei Hops von ihm im Diagramm entfernt sind.
SELECT PersonName, Friends
FROM (
SELECT
Person1.name AS PersonName,
STRING_AGG(Person2.name, '->') WITHIN GROUP (GRAPH PATH) AS Friends,
COUNT(Person2.name) WITHIN GROUP (GRAPH PATH) AS levels
FROM
Person AS Person1,
friendOf FOR PATH AS fo,
Person FOR PATH AS Person2
WHERE MATCH(SHORTEST_PATH(Person1(-(fo)->Person2){1,3}))
AND Person1.name = 'Jacob'
) Q
WHERE Q.levels = 2
F. Finden Sie Personen 1-3 Hops von einer bestimmten Person entfernt, die auch wie ein bestimmtes Restaurant
Im folgenden Beispiel wird der kürzeste Weg zwischen Jacob und allen Personen gefunden, mit denen er in der Grafik verbunden ist, 1-3 Hops von ihm entfernt. Die Abfrage filtert auch verbundene Personen, indem sie ein bestimmtes Restaurant mögen. Im folgenden Beispiel LAST_NODE(Person2)
wird der letzte Knoten für jeden kürzesten Pfad zurückgegeben. Der von ihnen abgerufene LAST_NODE
"letzte" Person
Knoten kann dann "verkettet" werden, um weitere Traversale zu finden, um die Restaurants zu finden, die ihnen gefallen.
SELECT
Person1.name AS PersonName,
STRING_AGG(Person2.name, '->') WITHIN GROUP (GRAPH PATH) AS Friends,
Restaurant.name
FROM
Person AS Person1,
friendOf FOR PATH AS fo,
Person FOR PATH AS Person2,
likes,
Restaurant
WHERE MATCH(SHORTEST_PATH(Person1(-(fo)->Person2){1,3}) AND LAST_NODE(Person2)-(likes)->Restaurant )
AND Person1.name = 'Jacob'
AND Restaurant.name = 'Ginger and Spice'
G. Suchen des kürzesten Pfads von einem bestimmten Knoten zu allen anderen Knoten im Diagramm, mit Ausnahme von "Schleifen"
Im folgenden Beispiel werden alle Personen gefunden, mit denen Alice im Diagramm verbunden ist, und den kürzesten Pfad, der von Alice bis zu all diesen Personen beginnt. Im Beispiel wird explizit nach "Schleifen" gesucht, bei denen der Start- und der Endknoten des Pfads identisch sind.
SELECT PersonName, Friends
FROM (
SELECT
Person1.name AS PersonName,
STRING_AGG(Person2.name, '->') WITHIN GROUP (GRAPH PATH) AS Friends,
LAST_VALUE(Person2.name) WITHIN GROUP (GRAPH PATH) AS LastNode
FROM
Person AS Person1,
friendOf FOR PATH AS fo,
Person FOR PATH AS Person2
WHERE MATCH(SHORTEST_PATH(Person1(-(fo)->Person2)+))
AND Person1.name = 'Alice'
) AS Q
WHERE Q.LastNode != 'Alice'