在SQL数据库中迭代社交图

在SQL数据库中迭代社交图,sql,recursion,graph,sql-server-2012,Sql,Recursion,Graph,Sql Server 2012,我存储简单的社交图信息,如下所示: 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 请注意,关系的标题是规范化的:因此

我存储简单的社交图信息,如下所示:

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中如何实现这一点?

非常酷的问题。虽然它是一个社交网络图,但它仍然是一个层次问题,即使层次结构可以从逻辑上转变为一个互联网络。在MSSQL中,您仍然希望使用
WITH
子句来执行递归查询,唯一的区别在于,由于存在多个互连,您需要确保唯一的结果,可以使用
DISTINCT
或在
WHERE
条件中使用
In
子句

这项工作:

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
        )
这里有一些测试数据,其中的关系比您最初和整个其他家庭的关系要多,以确保它不会超出预期

create table People ( PersonId bigint, Name nvarchar(200) );
create table Relationships ( FromPersonID bigint, ToPersonID bigint, Title nvarchar(200) );

insert into People values (1, 'John Smith');
insert into People values (2, 'Joan Smith');
insert into People values (3, 'Jack Smith');
insert into People values (4, 'Joey Smith');
insert into People values (9, 'Jaime Smith');

insert into People values (5, 'Edward Jones');
insert into People values (6, 'Emma Jones');
insert into People values (7, 'Eva Jones');
insert into People values (8, 'Eve Jones');

insert into Relationships values (1, 2, 'Spouse');
insert into Relationships values (1, 3, 'Parent');
insert into Relationships values (2, 3, 'Parent');
insert into Relationships values (3, 4, 'Child');
insert into Relationships values (2, 4, 'Child');
insert into Relationships values (4, 9, 'Child');

insert into Relationships values (5, 6, 'Spouse');
insert into Relationships values (5, 7, 'Parent');
insert into Relationships values (6, 7, 'Parent');
insert into Relationships values (5, 8, 'Child');

您正在使用哪个数据库?MS SQL Server 2012,谢谢!非常有趣的问题。你能详细说明你的问题吗?您的问题可以是“查找
人的兄弟姐妹
关系
”。如果可能,您可以向我们展示您期望的示例结果集吗?您知道吗?它声称在计算这些关系方面非常快。