我有两个表,第一个是人员数据
ID
Name
第二个有每个人的亲戚
Primary Key Field
Person (references person.id)
RelativeType (mother or father)
Parent (references person.id)
我正在尝试获取特定人的所有儿子和孙子,但我无法将孙子整合到查询结果中。我正在使用 SQL Server。
有任何想法吗?
我有两个表,第一个是人员数据
ID
Name
第二个有每个人的亲戚
Primary Key Field
Person (references person.id)
RelativeType (mother or father)
Parent (references person.id)
我正在尝试获取特定人的所有儿子和孙子,但我无法将孙子整合到查询结果中。我正在使用 SQL Server。
有任何想法吗?
您需要的查询很大程度上取决于您拥有多少级别的父子关系。如果您可以更改架构,我建议您转而使用HierarchyId
SQL 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
尝试这样的事情(未经测试):
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
感谢所有的答案,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
就像提到的递归 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
(这是在编辑问题之前使用母亲和父亲列,所以只需更改为Parent
有Mother OR Father
检查的地方)