![](/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.