![](/img/trans.png)
[英]How to find all parent node by a value in child node with SQL Server
[英]sql server graph query, find all paths to node
我有一個非常常見的問題,我試圖使用圖形查詢(sql server 2017)來解決。
C
。C
(具有 1 或 2 個連接)。這是創建此圖的完整腳本:
DROP TABLE IF EXISTS Person;
CREATE TABLE Person (userName VARCHAR(100) PRIMARY KEY) AS NODE;
INSERT INTO Person (userName) VALUES ('A'),('B'),('C'),('D'),('E'),('F');
DROP TABLE IF EXISTS Follow;
CREATE TABLE Follow AS EDGE;
INSERT INTO Follow ($from_id, $to_id) VALUES (
(SELECT $node_id FROM dbo.Person WHERE userName = 'A'),
(SELECT $node_id FROM dbo.Person WHERE userName = 'E')),
((SELECT $node_id FROM dbo.Person WHERE userName = 'E'),
(SELECT $node_id FROM dbo.Person WHERE userName = 'C')),
((SELECT $node_id FROM dbo.Person WHERE userName = 'C'),
(SELECT $node_id FROM dbo.Person WHERE userName = 'A')),
((SELECT $node_id FROM dbo.Person WHERE userName = 'A'),
(SELECT $node_id FROM dbo.Person WHERE userName = 'F')),
((SELECT $node_id FROM dbo.Person WHERE userName = 'F'),
(SELECT $node_id FROM dbo.Person WHERE userName = 'B')),
((SELECT $node_id FROM dbo.Person WHERE userName = 'B'),
(SELECT $node_id FROM dbo.Person WHERE userName = 'F')),
((SELECT $node_id FROM dbo.Person WHERE userName = 'B'),
(SELECT $node_id FROM dbo.Person WHERE userName = 'E')),
((SELECT $node_id FROM dbo.Person WHERE userName = 'E'),
(SELECT $node_id FROM dbo.Person WHERE userName = 'B'));
這個查詢不起作用,因為它只給我直接關系:
SELECT Person1.userName as userName1, Person2.userName as userName2
FROM Person as Person1, Follow, Person as Person2
WHERE MATCH(Person1-(Follow)->Person2)
AND Person2.userName = 'C'
您可以嘗試以下操作:
SELECT
p1.userName,
p1.userName as StartNode,
LAST_VALUE(p2.userName) WITHIN GROUP (GRAPH PATH) AS FinalNode,
STRING_AGG(p2.userName,'->') WITHIN GROUP (GRAPH PATH) AS [Edges Path],
COUNT(p2.userName) WITHIN GROUP (GRAPH PATH) AS Levels
FROM
dbo.Person p1,
dbo.Person FOR PATH p2,
dbo.Follow FOR PATH Follow
WHERE
MATCH(SHORTEST_PATH(p1(-(Follow)->p2)+))
AND p1.userName = 'C';
要查找節點的所有傳入連接,我們需要為最終節點包裝查詢和過濾器,如下所示:
SELECT
username, StartNode, [Edges Path], FinalNode, Levels
FROM (
SELECT
P1.username,
P1.username as StartNode,
STRING_AGG(P2.userName,'->') WITHIN GROUP (GRAPH PATH) AS [Edges Path],
LAST_VALUE(P2.userName) WITHIN GROUP (GRAPH PATH) AS FinalNode,
COUNT(P2.userName) WITHIN GROUP (GRAPH PATH) AS Levels
FROM
Person P1,
Person FOR PATH P2,
Follow FOR PATH Follow
WHERE
MATCH(SHORTEST_PATH(P1(-(Follow)->P2)))
) AS Q
WHERE Q.FinalNode = 'C'
為了限制跳躍的級別或數量,我們可以提供遞歸量詞來代替 (+ --- 一個或多個),如下所示:
SELECT
username, StartNode, [Edges Path], FinalNode, Levels
FROM (
SELECT
P1.username,
P1.username as StartNode,
STRING_AGG(P2.userName,'->') WITHIN GROUP (GRAPH PATH) AS [Edges Path],
LAST_VALUE(P2.userName) WITHIN GROUP (GRAPH PATH) AS FinalNode,
COUNT(P2.userName) WITHIN GROUP (GRAPH PATH) AS Levels
FROM
Person P1,
Person FOR PATH P2,
Follow FOR PATH Follow
WHERE
MATCH(SHORTEST_PATH(P1(-(Follow)->P2){1,3}))
) AS Q
WHERE Q.FinalNode = 'C'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.