很酷的问题。虽然它是一个社交网络图,但它仍然是一个层次问题,即使层次结构在逻辑上可以变成一个互连网络。在 MSSQL 中,您仍然希望使用WITH
子句进行递归查询,唯一的区别是,由于需要多重互连来确保结果的唯一性,无论是在条件中使用子句DISTINCT
还是使用子句。IN
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
)
这里有一些测试数据,它们的关系比你最初和整个其他家庭的关系要多,以确保它不会超出预期。
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');