gpt4 book ai didi

sql-server - SQL Server 图 : how identify subgraphs?

转载 作者:行者123 更新时间:2023-12-04 08:57:06 26 4
gpt4 key购买 nike

我有 [Friends] 节点和 [Link] 边缘。我的任务是找出哪个子图(网络)属于哪个 friend 。对此的简单说明:
enter image description here
这是我如何构造节点、边和填充数据的代码:

--  Construct nodes
DROP TABLE IF EXISTS [dbo].[Friend];
CREATE TABLE [dbo].[Friend] (
[FriendId] INT IDENTITY PRIMARY KEY
, [Name] NVARCHAR(256) NOT NULL
) AS NODE;

INSERT INTO [dbo].[Friend]([Name]) VALUES
('Jon'), ('Rita'), ('Ben'), ('Andrew'), ('Joe'), ('Patrick')
, ('Mike'), ('Thomas'), ('Kelly'), ('Lily'), ('Kira');

-- Construct edges
DROP TABLE IF EXISTS [dbo].[Link];
CREATE TABLE [dbo].[Link] (
[LinkDirection] BIT NOT NULL
, [FriendIdFrom] INT NOT NULL
, [FriendIdTo] INT NOT NULL
)AS EDGE;

INSERT INTO [dbo].[Link] ($from_id, $to_id, [LinkDirection], [FriendIdFrom], [FriendIdTo])
-- Network 1
SELECT [f1].$node_id, [f2].$node_id, 1, [f1].[FriendId], [f2].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Jon' AND [f2].[Name] = 'Rita'
UNION ALL SELECT [f1].$node_id, [f2].$node_id, 1, [f1].[FriendId], [f2].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Jon' AND [f2].[Name] = 'Ben'
UNION ALL SELECT [f1].$node_id, [f2].$node_id, 1, [f1].[FriendId], [f2].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Jon' AND [f2].[Name] = 'Andrew'
UNION ALL SELECT [f1].$node_id, [f2].$node_id, 1, [f1].[FriendId], [f2].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Andrew' AND [f2].[Name] = 'Joe'
UNION ALL SELECT [f1].$node_id, [f2].$node_id, 1, [f1].[FriendId], [f2].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Andrew' AND [f2].[Name] = 'Patrick'
-- Network 2
UNION ALL SELECT [f1].$node_id, [f2].$node_id, 1, [f1].[FriendId], [f2].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Mike' AND [f2].[Name] = 'Thomas'
UNION ALL SELECT [f1].$node_id, [f2].$node_id, 1, [f1].[FriendId], [f2].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Mike' AND [f2].[Name] = 'Kelly'
-- Network 3
UNION ALL SELECT [f1].$node_id, [f2].$node_id, 1, [f1].[FriendId], [f2].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Lily' AND [f2].[Name] = 'Kira'

-- To have bi-directional link

-- Network 1
UNION ALL SELECT [f2].$node_id, [f1].$node_id, 0, [f2].[FriendId], [f1].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Jon' AND [f2].[Name] = 'Rita'
UNION ALL SELECT [f2].$node_id, [f1].$node_id, 0, [f2].[FriendId], [f1].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Jon' AND [f2].[Name] = 'Ben'
UNION ALL SELECT [f2].$node_id, [f1].$node_id, 0, [f2].[FriendId], [f1].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Jon' AND [f2].[Name] = 'Andrew'
UNION ALL SELECT [f2].$node_id, [f1].$node_id, 0, [f2].[FriendId], [f1].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Andrew' AND [f2].[Name] = 'Joe'
UNION ALL SELECT [f2].$node_id, [f1].$node_id, 0, [f2].[FriendId], [f1].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Andrew' AND [f2].[Name] = 'Patrick'
-- Network 2
UNION ALL SELECT [f2].$node_id, [f1].$node_id, 0, [f2].[FriendId], [f1].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Mike' AND [f2].[Name] = 'Thomas'
UNION ALL SELECT [f2].$node_id, [f1].$node_id, 0, [f2].[FriendId], [f1].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Mike' AND [f2].[Name] = 'Kelly'
-- Network 3
UNION ALL SELECT [f2].$node_id, [f1].$node_id, 0, [f2].[FriendId], [f1].[FriendId] FROM [dbo].[Friend] [f1] INNER JOIN [dbo].[Friend] [f2] ON [f1].[Name] = 'Lily' AND [f2].[Name] = 'Kira';
我有代码,如何列出所有可能的路径:
SELECT  
[StartNode] = [f1].[Name]
, [FinalNode] = LAST_VALUE([f2].[name]) WITHIN GROUP (GRAPH PATH)
, [Steps] = COUNT([f2].[FriendId]) WITHIN GROUP (GRAPH PATH)
, [Path] = [f1].[Name] + ' => ' + STRING_AGG([f2].[Name],' => ') WITHIN GROUP (GRAPH PATH)
, [Network] = '???'
--, *
FROM
[dbo].[Friend] [f1]
, [dbo].[Friend] FOR PATH [f2]
, [dbo].[Link] FOR PATH [l]
WHERE
MATCH(SHORTEST_PATH(f1(-(l)->f2)+));
但是,我很难在这里添加网络标识符(唯一数字,文本,无关紧要):(
也许有人以前有经验,可以提供帮助吗?
预期结果是:
---------------------------------------------------------------------------------
|StartNode | FinalNode | Steps | Path |Network|
|------------| -----------| -------| -----------------------------------|-------|
|Jon | Rita | 1 | Jon => Rita |1 |
|Jon | Ben | 1 | Jon => Ben |1 |
|Jon | Andrew | 1 | Jon => Andrew |1 |
|Rita | Jon | 1 | Rita => Jon |1 |
|Ben | Jon | 1 | Ben => Jon |1 |
|Andrew | Jon | 1 | Andrew => Jon |1 |
|Andrew | Joe | 1 | Andrew => Joe |1 |
|Andrew | Patrick | 1 | Andrew => Patrick |1 |
|Joe | Andrew | 1 | Joe => Andrew |1 |
|Patrick | Andrew | 1 | Patrick => Andrew |1 |
|Mike | Thomas | 1 | Mike => Thomas |2 |
|Mike | Kelly | 1 | Mike => Kelly |2 |
|Thomas | Mike | 1 | Thomas => Mike |2 |
|Kelly | Mike | 1 | Kelly => Mike |2 |
|Lily | Kira | 1 | Lily => Kira |3 |
|Kira | Lily | 1 | Kira => Lily |3 |
|Jon | Jon | 2 | Jon => Andrew => Jon |1 |
|Jon | Joe | 2 | Jon => Andrew => Joe |1 |
|Jon | Patrick | 2 | Jon => Andrew => Patrick |1 |
|Rita | Rita | 2 | Rita => Jon => Rita |1 |
|Rita | Ben | 2 | Rita => Jon => Ben |1 |
|Rita | Andrew | 2 | Rita => Jon => Andrew |1 |
|Ben | Rita | 2 | Ben => Jon => Rita |1 |
|Ben | Ben | 2 | Ben => Jon => Ben |1 |
|Ben | Andrew | 2 | Ben => Jon => Andrew |1 |
|Andrew | Rita | 2 | Andrew => Jon => Rita |1 |
|Andrew | Ben | 2 | Andrew => Jon => Ben |1 |
|Andrew | Andrew | 2 | Andrew => Jon => Andrew |1 |
|Joe | Jon | 2 | Joe => Andrew => Jon |1 |
|Joe | Joe | 2 | Joe => Andrew => Joe |1 |
|Joe | Patrick | 2 | Joe => Andrew => Patrick |1 |
|Patrick | Jon | 2 | Patrick => Andrew => Jon |1 |
|Patrick | Joe | 2 | Patrick => Andrew => Joe |1 |
|Patrick | Patrick | 2 | Patrick => Andrew => Patrick |1 |
|Mike | Mike | 2 | Mike => Thomas => Mike |2 |
|Thomas | Thomas | 2 | Thomas => Mike => Thomas |2 |
|Thomas | Kelly | 2 | Thomas => Mike => Kelly |2 |
|Kelly | Thomas | 2 | Kelly => Mike => Thomas |2 |
|Kelly | Kelly | 2 | Kelly => Mike => Kelly |2 |
|Lily | Lily | 2 | Lily => Kira => Lily |3 |
|Kira | Kira | 2 | Kira => Lily => Kira |3 |
|Rita | Joe | 3 | Rita => Jon => Andrew => Joe |1 |
|Rita | Patrick | 3 | Rita => Jon => Andrew => Patrick |1 |
|Ben | Joe | 3 | Ben => Jon => Andrew => Joe |1 |
|Ben | Patrick | 3 | Ben => Jon => Andrew => Patrick |1 |
|Joe | Rita | 3 | Joe => Andrew => Jon => Rita |1 |
|Joe | Ben | 3 | Joe => Andrew => Jon => Ben |1 |
|Patrick | Rita | 3 | Patrick => Andrew => Jon => Rita |1 |
|Patrick | Ben | 3 | Patrick => Andrew => Jon => Ben |1 |
---------------------------------------------------------------------------------
简而言之,我需要如何为这些网络赋予唯一名称,并与人进行映射。

最佳答案

select *, 
min([FinalNode]) over(partition by [StartNode]) as NetworkOf,
----in case of duplicate names, also use partition by StartNodeId instead of [StartNode]...
min(FinalFriendId) over(partition by [StartNode]) as NetworkId
from
(
SELECT
[StartNode] = [f1].[Name]
, [FinalNode] = LAST_VALUE([f2].[name]) WITHIN GROUP (GRAPH PATH)
, [Steps] = COUNT([f2].[FriendId]) WITHIN GROUP (GRAPH PATH)
, [Path] = [f1].[Name] + ' => ' + STRING_AGG([f2].[Name],' => ') WITHIN GROUP (GRAPH PATH)
, FinalFriendId = LAST_VALUE(f2.FriendId) WITHIN GROUP (GRAPH PATH)

FROM
[dbo].[Friend] [f1]
, [dbo].[Friend] FOR PATH [f2]
, [dbo].[Link] FOR PATH [l]
WHERE
MATCH(SHORTEST_PATH(f1(-(l)->f2)+))
) as src;

关于sql-server - SQL Server 图 : how identify subgraphs?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63767196/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com