如何在 SQL 中获得树的第三层
How to get the third level of a tree in SQL
我的目标是使用SQL服务器列出一个家庭的第四代。
图中的示例家谱(基于 id)
FAMILY TREE
我的表格是:
家庭
+------+-----------------+
| f_id | f_name |
+------+-----------------+
| 1 | Name Surname 1 |
| 2 | Name Surname 2 |
| 3 | Name Surname 3 |
| 4 | Name Surname 4 |
| 5 | Name Surname 5 |
| 6 | Name Surname 6 |
| 7 | Name Surname 7 |
| 8 | Name Surname 8 |
| 9 | Name Surname 9 |
| 10 | Name Surname 10 |
+------+-----------------+
关系
+----------+---------+
| r_parent | r_child |
+----------+---------+
| 1 | 2 |
| 1 | 3 |
| 2 | 4 |
| 2 | 5 |
| 3 | 6 |
| 3 | 7 |
| 3 | 8 |
| 7 | 9 |
| 8 | 10 |
+----------+---------+
这是我需要的结果:
9 Name Surname
10 Name Surname
对于固定数量(且相对较少)的级别,您可以加入:
select f.*
from relations r1
inner join relations r2 on r2.r_parent = r1.r_child
inner join relations r3 on r3.r_parent = r2.r_child
inner join family f on f.f_id = r3.r_child
where not exists (select 1 from relations r0 where r0.r_child = r1.r_parent)
更通用的方法是使用递归查询:
with cte as (
select r.r_parent, r.r_child, 1 lvl
from relations r
where not exists (select 1 from relations r0 where r0.r_child = r.r_parent)
union all
select r.r_parent, r.r_child, c.lvl + 1
from relations r
inner join cte c on c.r_child = r.r_parent
where c.lvl < 3
)
select f.*
from family f
inner join cte c on c.r_child = f.f_id
where c.lvl = 3
您需要使用不同的别名进行相同的连接以获得最后一代
另一种选择是进行递归 CTE。
SELECT
G4.*
FROM relations GR1
INNER JOIN family G1 ON GR1.r_parent = G1.f_id
INNER JOIN family G2 on GR1.r_child = G2.f_id
INNER JOIN relations GR2 ON GR2.r_parent = G2.f_id
INNER JOIN family G3 ON GR2.r_child = G3.f_id
INNER JOIN relations GR3 ON GR3.r_parent = G3.f_id
INNER JOIN family G4 ON GR3.r_child = G4.f_id
使用的脚本是:
CREATE TABLE family(f_id int ,f_name nvarchar (200))
INSERT INTO family
VALUES
(1, 'Name Surname 1')
, (2, 'Name Surname 2')
, (3, 'Name Surname 3')
, (4, 'Name Surname 4')
, (5, 'Name Surname 5')
, (6, 'Name Surname 6')
, (7, 'Name Surname 7')
, (8, 'Name Surname 8')
, (9, 'Name Surname 9')
, (10, 'Name Surname 10')
CREATE TABLE relations (r_parent int, r_child int)
INSERT INTO relations VALUES (1, 2), (1, 3), (2,4), (2,5), (3,6), (3,7), (3,8), (7,9), (8,10)
SELECT
G4.*
FROM relations GR1
INNER JOIN family G1 ON GR1.r_parent = G1.f_id
INNER JOIN family G2 on GR1.r_child = G2.f_id
INNER JOIN relations GR2 ON GR2.r_parent = G2.f_id
INNER JOIN family G3 ON GR2.r_child = G3.f_id
INNER JOIN relations GR3 ON GR3.r_parent = G3.f_id
INNER JOIN family G4 ON GR3.r_child = G4.f_id
DROP TABLE family
DROP TABLE relations
我的目标是使用SQL服务器列出一个家庭的第四代。
图中的示例家谱(基于 id)
FAMILY TREE
我的表格是:
家庭
+------+-----------------+
| f_id | f_name |
+------+-----------------+
| 1 | Name Surname 1 |
| 2 | Name Surname 2 |
| 3 | Name Surname 3 |
| 4 | Name Surname 4 |
| 5 | Name Surname 5 |
| 6 | Name Surname 6 |
| 7 | Name Surname 7 |
| 8 | Name Surname 8 |
| 9 | Name Surname 9 |
| 10 | Name Surname 10 |
+------+-----------------+
关系
+----------+---------+
| r_parent | r_child |
+----------+---------+
| 1 | 2 |
| 1 | 3 |
| 2 | 4 |
| 2 | 5 |
| 3 | 6 |
| 3 | 7 |
| 3 | 8 |
| 7 | 9 |
| 8 | 10 |
+----------+---------+
这是我需要的结果:
9 Name Surname
10 Name Surname
对于固定数量(且相对较少)的级别,您可以加入:
select f.*
from relations r1
inner join relations r2 on r2.r_parent = r1.r_child
inner join relations r3 on r3.r_parent = r2.r_child
inner join family f on f.f_id = r3.r_child
where not exists (select 1 from relations r0 where r0.r_child = r1.r_parent)
更通用的方法是使用递归查询:
with cte as (
select r.r_parent, r.r_child, 1 lvl
from relations r
where not exists (select 1 from relations r0 where r0.r_child = r.r_parent)
union all
select r.r_parent, r.r_child, c.lvl + 1
from relations r
inner join cte c on c.r_child = r.r_parent
where c.lvl < 3
)
select f.*
from family f
inner join cte c on c.r_child = f.f_id
where c.lvl = 3
您需要使用不同的别名进行相同的连接以获得最后一代 另一种选择是进行递归 CTE。
SELECT
G4.*
FROM relations GR1
INNER JOIN family G1 ON GR1.r_parent = G1.f_id
INNER JOIN family G2 on GR1.r_child = G2.f_id
INNER JOIN relations GR2 ON GR2.r_parent = G2.f_id
INNER JOIN family G3 ON GR2.r_child = G3.f_id
INNER JOIN relations GR3 ON GR3.r_parent = G3.f_id
INNER JOIN family G4 ON GR3.r_child = G4.f_id
使用的脚本是:
CREATE TABLE family(f_id int ,f_name nvarchar (200))
INSERT INTO family
VALUES
(1, 'Name Surname 1')
, (2, 'Name Surname 2')
, (3, 'Name Surname 3')
, (4, 'Name Surname 4')
, (5, 'Name Surname 5')
, (6, 'Name Surname 6')
, (7, 'Name Surname 7')
, (8, 'Name Surname 8')
, (9, 'Name Surname 9')
, (10, 'Name Surname 10')
CREATE TABLE relations (r_parent int, r_child int)
INSERT INTO relations VALUES (1, 2), (1, 3), (2,4), (2,5), (3,6), (3,7), (3,8), (7,9), (8,10)
SELECT
G4.*
FROM relations GR1
INNER JOIN family G1 ON GR1.r_parent = G1.f_id
INNER JOIN family G2 on GR1.r_child = G2.f_id
INNER JOIN relations GR2 ON GR2.r_parent = G2.f_id
INNER JOIN family G3 ON GR2.r_child = G3.f_id
INNER JOIN relations GR3 ON GR3.r_parent = G3.f_id
INNER JOIN family G4 ON GR3.r_child = G4.f_id
DROP TABLE family
DROP TABLE relations