我正在尝试使用我有限的SQL技能来构造递归CTE查询。 我有一个建模的家谱两个表:家族树的递归CTE不会递归
CREATE TABLE "Relation" (
"id" integer not null primary key autoincrement,
"person1Id" integer,
"person2Id" integer,
foreign key("person1Id") references "Person"("id"),
foreign key("person2Id") references "Person"("id"));
CREATE TABLE "Person" (
"id" integer not null primary key autoincrement,
"name" varchar(255),
"gender" varchar(255),
"bornToId" integer,
foreign key("bornToId") references "Relation"("id"));
我试图让一个sqlfiddle,但我不断收到“哎呀,出事了”,所以我会在这里粘贴插入:
INSERT INTO `Person` (id,name,gender,bornToId) VALUES
(1,'William I','M',NULL),
(2,'Matilde of Flanders','F',NULL),
(3,'William Rufus','M',1),
(4,'Henry I','M',1),
(5,'Matilde of Scotland','F',NULL),
(6,'William Adelin','M',2),
(7,'Matilde Holy Roman Empress','F',2),
(8,'Geoffrey of Anjou','M',NULL),
(9,'Henry II','M',3),
(10,'Eleanor of Aquitane','F',NULL),
(11,'Richard I','M',4),
(12,'John','M',4),
(13,'Robert Curthose','M',1),
(14,'Adeliza','F',NULL),
(15,'Adela of Normandy','F',1),
(16,'Stephen II Henry','M',NULL),
(17,'Stephen of Blois','M',6);
INSERT INTO `Relation` (id,person1Id,person2Id) VALUES (1,1,2),
(2,4,5),
(3,7,8),
(4,9,10),
(5,4,14),
(6,15,16);
我开始将问题分解为子查询。这些,因为我希望他们(sqlite的3.14.0,DB浏览器,在Mac上)所有的工作:
找到0,1或多种关系(合作伙伴)的人
select
pers.id as id,
pers.name as name,
partner.id as partnerId,
partner.name as partnerName
from Person pers
join Relation
on pers.id = Relation.person1Id
or pers.id = Relation.person2Id
join Person partner
on (partner.id = Relation.person1Id and
partner.id <> pers.id)
or (partner.id = Relation.person2Id and
partner.id <> pers.id)
where pers.id = 4
发现一个人的父母(如果有的话)
select
parent1.id as parent1Id,
parent1.name as parent1Name,
parent2.id as parent2Id,
parent2.name as parent2Name,
parents.id as parentsId
from Person pers
left join Relation parents on pers.bornToId = parents.id
left join Person parent1 on parents.person1Id = parent1.id
left join Person parent2 on parents.person2Id = parent2.id
where pers.id = 4
结合上述两个也可以,但是我会在这里忽略该查询。
找到属于关系
select pers.id, pers.name
from Person pers
where pers.bornToId = 1
现在的孩子,把这个都聚集在递归CTE查询造成我的问题。我迄今为止的尝试导致了这个查询的怪物,但它只是返回一个记录(“1”“威廉一世”“2”“佛罗里达的Matilde”“NULL”“NULL”“NULL”“NULL”),所以显然它不会进入递归。
WITH FamilyTree (
id,
name,
partnerId,
partnerName,
parent1Id,
parent1Name,
parent2Id,
parent2Name,
parentsId
)
AS (
select
pers.id as id,
pers.name as name,
partner.id as partnerId,
partner.name as partnerName,
parent1.id as parent1Id,
parent1.name as parent1Name,
parent2.id as parent2Id,
parent2.name as parent2Name,
parents.id as parentsId
from Person pers
left join Relation
on pers.id = Relation.person1Id
or pers.id = Relation.person2Id
left join Person partner
on (partner.id = Relation.person1Id and
partner.id <> pers.id)
or (partner.id = Relation.person2Id and
partner.id <> pers.id)
left join Relation parents on pers.bornToId = parents.id
left join Person parent1 on parents.person1Id = parent1.id
left join Person parent2 on parents.person2Id = parent2.id
where pers.id = 1
union all
select
pers.id as id,
pers.name as name,
partner.id as partnerId,
partner.name as partnerName,
parent1.id as parent1Id,
parent1.name as parent1Name,
parent2.id as parent2Id,
parent2.name as parent2Name,
parents.id as parentsId
from Person pers
left join Relation
on pers.id = Relation.person1Id
or pers.id = Relation.person2Id
left join Person partner
on (partner.id = Relation.person1Id and
partner.id <> pers.id)
or (partner.id = Relation.person2Id and
partner.id <> pers.id)
left join Relation parents on pers.bornToId = parents.id
left join Person parent1 on parents.person1Id = parent1.id
left join Person parent2 on parents.person2Id = parent2.id
JOIN FamilyTree AS fam
ON pers.bornToId = fam.parentsId
)
select
id,
name,
partnerId,
partnerName,
parent1Id,
parent1Name,
parent2Id,
parent2Name
from FamilyTree
我在这方面花了很多时间,所以我认为是时候问专家了。
如果你想知道,最终目标是到嵌套JavaScript对象,如:
{
...
relations: [{
...
children: [{
这样我就可以在D3树使用它。
在CTE末尾添加“LIMIT 20”。结果是什么? –
我在正式结束之前就放下了)。我再次得到“查询成功执行...花了5毫秒”。 – devboell
哦,等等,它返回的东西(有和没有LIMIT),一个记录: “1” \t “威廉一世” \t “2” \t “弗兰德的马蒂尔德” \t “NULL” \t “NULL” \t “NULL” \t “NULL”我认为这仍然是前一个查询的结果。我将编辑该问题 – devboell