【发布时间】:2016-04-16 09:02:43
【问题描述】:
考虑一个包含以下列的数据库表:
- mathematician_id
- 姓名
- 顾问1
- 顾问2
数据库表示来自Math Genealogy Project 的数据,其中每个数学家通常只有一个顾问,但也有两个顾问的情况。
视觉帮助使事情更清晰:
我如何计算每个数学家的后代数量?
我可能应该使用公用表表达式(WITH RECURSIVE),但我现在几乎被困住了。我发现的所有类似示例都处理只有一个父级而不是两个父级的层次结构。
更新:
我修改了Vladimir Baranov 提供的 SQL Server 解决方案,使其也适用于 PostgreSQL:
WITH RECURSIVE cte AS (
SELECT m.id as start_id,
m.id,
m.name,
m.advisor1,
m.advisor2,
1 AS level
FROM public.mathematicians AS m
UNION ALL
SELECT cte.start_id,
m.id,
m.name,
m.advisor1,
m.advisor2,
cte.level + 1 AS level
FROM public.mathematicians AS m
INNER JOIN cte ON cte.id = m.advisor1
OR cte.id = m.advisor2
),
cte_distinct AS (
SELECT DISTINCT start_id, id
FROM cte
)
SELECT cte_distinct.start_id,
m.name,
COUNT(*)-1 AS descendants_count
FROM cte_distinct
INNER JOIN public.mathematicians AS m ON m.id = cte_distinct.start_id
GROUP BY cte_distinct.start_id, m.name
ORDER BY cte_distinct.start_id
【问题讨论】:
-
[从技术上讲,你的“树”是一个 DAG ] 你可以重新定义 descendant :如果存在 ,B 是 A 的后代从 A 到 B 的至少一条(有向)路径。然后计算每个 A 的 B 数量。
-
您使用什么 DBMS?
标签: sql postgresql recursion common-table-expression hierarchical-data