0

我有两个表,第一个是人员数据

ID
Name

第二个有每个人的亲戚

Primary Key Field
Person (references person.id)
RelativeType (mother or father)
Parent (references person.id)

我正在尝试获取特定人的所有儿子和孙子,但我无法将孙子整合到查询结果中。我正在使用 SQL Server。

有任何想法吗?

4

4 回答 4

1

您需要的查询很大程度上取决于您拥有多少级别的父子关系。如果您可以更改架构,我建议您转而使用HierarchyIdSQL Server 特定的数据类型。看看这里

在下文中,我假设您只有 2 个级别。父亲 - 儿子 - 孙子

;WITH Sons AS (
    SELECT pdf.Id, pdf.Name, pdd.Id ParentId, pdd.Name Parent FROM PersonData pdf
    JOIN PersonRelative pr ON pdf.Id = pr.Parent
    JOIN PersonData pdd ON pr.Person = pdd.Id //Selecting all Parents
)

SELECT pd.Name, s.Name Son, 'Son' Type FROM PersonData pd
JOIN Sons s on pd.Id = s.ParentId

UNION

SELECT pd.Name, gs.Name Son, 'GrandSon' Type FROM PersonData pd
JOIN Sons s on pd.Id = s.ParentId
JOIN Sons gs on s.Id = gs.ParentId
于 2013-09-04T12:49:22.583 回答
0

尝试这样的事情(未经测试):

declare @person bigint = 123
;with cte as
(
    select p.id, p.name, r.relativetype, r.parent, 0 decendantLevel 
    from  person p
    inner join relatives r
    on p.id = r.person
    where p.id = @person --select the ancestor who's tree we're interested in (if we don't want to include the person themselves change p.id to r.parent)

    union all

    select p.id, p.name, r.relativetype, r.parent, c.decendantLevel + 1
    from  person p
    inner join relatives r
    on p.id = r.person
    inner join cte c
    on c.id = r.parentid
)
select * from cte order by decendantLevel 
于 2013-09-04T12:41:32.437 回答
0

感谢所有的答案,CTE 是要走的路。我从每个答案中提取部分并以此结束

with Sons as (select P1.Person as PersonSon from Persons 
join relatives as P1 on P1.Parent = Persons.Id
where Persons.Name = 'Mary') 

select Id from Persons 
join (
select P2.Person as PersonSon from Relatives as P2
join Sons on P2.Parent = Sons.PersonSon ) as P3 on Persons.Id = P3.PersonSon
union all select Sons.PersonSon from Sons
于 2013-09-04T13:23:05.227 回答
0

就像提到的递归 CTE是实现这一点的方法:

DECLARE @PersonToFind INT
SET @PersonToFind = 1

;WITH RCTE AS 
(
    SELECT Person, CAST('Child' AS NVARCHAR(MAX)) AS Relation 
    FROM PersonRelations 
    WHERE Father = @PersonToFind OR Mother = @PersonToFind 

    UNION ALL

    SELECT pr.Person, 'Grand' + r.Relation
    FROM PersonRelations pr 
        INNER JOIN RCTE r ON r.Person = pr.Mother OR r.Person = pr.Father
)
SELECT r.*, p.Name 
FROM RCTE r
    LEFT JOIN Person p ON r.Person = p.ID

SQLFiddle 演示

(这是在编辑问题之前使用母亲和父亲列,所以只需更改为ParentMother OR Father检查的地方)

于 2013-09-04T12:45:40.577 回答