SQL Server 递归自联接

Posted

技术标签:

【中文标题】SQL Server 递归自联接【英文标题】:SQL Server recursive self join 【发布时间】:2017-08-14 18:50:16 【问题描述】:

我有一个简单的类别表,包含以下列:

身份证 姓名 父母身份

因此,无限数量的类别可以是一个类别的子类别。以下面的层次结构为例:

我希望,在一个返回类别“商务笔记本电脑”的简单查询中,还返回一个包含所有父项、逗号分隔符或其他内容的列:

或者举个例子:

【问题讨论】:

看看:dba.stackexchange.com/questions/160924/… 一个重要的澄清问题:一个类别总是只有一个父级吗? @LaughingVergil:它永远不会有超过一个直接父级,但它也可以没有父级。 【参考方案1】:

递归 cte 来救援....

创建并填充示例表(在您以后的问题中保存我们这一步):

DECLARE @T as table
(
    id int,
    name varchar(100),
    parent_id int
)

INSERT INTO @T VALUES
(1, 'A', NULL),
(2, 'A.1', 1),
(3, 'A.2', 1),
(4, 'A.1.1', 2),
(5, 'B', NULL),
(6, 'B.1', 5),
(7, 'B.1.1', 6),
(8, 'B.2', 5),
(9, 'A.1.1.1', 4),
(10, 'A.1.1.2', 4)

cte:

;WITH CTE AS
(
    SELECT id, name, name as path, parent_id
    FROM @T 
    WHERE parent_id IS NULL
    UNION ALL
    SELECT t.id, t.name, cast(cte.path +','+ t.name as varchar(100)), t.parent_id
    FROM @T t
    INNER JOIN CTE ON t.parent_id = CTE.id
)

查询:

SELECT id, name, path
FROM CTE

结果:

id      name        path
1       A           A
5       B           B
6       B.1         B,B.1
8       B.2         B,B.2
7       B.1.1       B,B.1,B.1.1
2       A.1         A,A.1
3       A.2         A,A.2
4       A.1.1       A,A.1,A.1.1
9       A.1.1.1     A,A.1,A.1.1,A.1.1.1
10      A.1.1.2     A,A.1,A.1.1,A.1.1.2

See online demo on rextester

【讨论】:

@ZoharPeled:太棒了。我没想到会有这么完整的答案。我将来肯定会包括样本数据。以下是我的一些实际数据的实际查询:link

以上是关于SQL Server 递归自联接的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server - 使用内部查询自联接更新值的代码

进行递归自联接的最简单方法?

Spring Boot JPA:在自联接关系中的 JSON 视图上递归

Oracle DB 使用连接显示多个表中的数据

了解在 SQL 查询的自联接中使用“Between”条件时的逻辑查询处理

与 MS SQL Server 完全联接