Sex*_*yMF 2 sql-server graph sql-graph
我有一个非常常见的问题,我试图使用图形查询来解决(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'));
Run Code Online (Sandbox Code Playgroud)
这个查询不起作用,因为它只给我直接关系:
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'
Run Code Online (Sandbox Code Playgroud)
你可以尝试如下所示:
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';
Run Code Online (Sandbox Code Playgroud)
要查找节点的所有传入连接,我们需要包装最终节点的查询和过滤器,如下所示:
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'
Run Code Online (Sandbox Code Playgroud)
为了限制级别或跳数,我们可以提供递归量词来代替 (+ --- 一个或多个),如下所示:
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'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2109 次 |
| 最近记录: |