[Friends] ノードと [Link] エッジがあります。私の仕事は、サブグラフ(ネットワーク)がどの友達に属しているかを把握することです。これの簡単な図:
ノード、エッジを構築し、データを入力するコードは次のとおりです。
-- 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 |
---------------------------------------------------------------------------------
簡単に言うと、これらのネットワークに一意の名前を付けて、人物とマッピングする方法が必要です。