我存储简单的社交图形信息,如下:
People ( PersonId bigint, Name nvarchar )
Relationships ( From bigint, To bigint, Title nvarchar )
所以数据看起来像这样:
People
1, John Smith
2, Joan Smith
3, Jack Smith
Relationships
1, 2, Spouse
1, 3, Parent
2, 3, Parent
请注意,关系的标题是规范化的:所以没有“丈夫”和“妻子”,只有“配偶”,这也避免了需要创建两个形成相同链接的单独关系,同样适用于“父母” “而不是”儿子“或”女儿“。
问题是如何遍历整个连接图(即只返回单个族),例如,找到兄弟姐妹而无需创建显式的兄弟关系条目。节点不一定需要以任何特定顺序返回。我可能还希望仅返回距离给定起始节点最多N
度的节点。
我知道您可以在最近的SQL语言版本中使用一些新技巧来执行递归SQL SELECT语句,但这不一定是递归操作,因为这些关系可以表示循环非方向图(想想是否添加了“Friend”)作为一种关系)。你会如何在SQL中做到这一点?
答案 0 :(得分:2)
非常酷的问题。虽然它是一个社交网络图,但它仍然是一个分层问题,即使层次结构可以在逻辑上变成互连网络。在MSSQL中,您仍然希望使用WITH
子句来执行递归查询,唯一的区别是,由于需要多个互连,您需要使用DISTINCT
或使用{{来确保唯一结果IN
条件中的1}}子句。
这有效:
WHERE
这里有一些测试数据与你原来的关系比其他家庭更多,以确保它没有超出预期。
DECLARE @PersonID bigint;
SET @PersonID = 1;
WITH RecurseRelations (PersonID, OriginalPersonID)
AS
(
SELECT PersonID, PersonId OriginalPersonID
FROM People
UNION ALL
SELECT ToPersonID, RR.OriginalPersonID
FROM Relationships R
INNER JOIN
RecurseRelations RR
ON
R.FromPersonID = RR.PersonID
)
SELECT PersonId, Name
FROM People
WHERE PersonId IN
(
SELECT PersonID
FROM RecurseRelations
WHERE OriginalPersonID = @PersonID
)