T-SQL 查询以提取 Parent 的标签和所有 Children 的标签
T-SQL Query to Pull a Parent's Tags and all Children's Tags
背景
我在 SQL 服务器中有一个数据库架构,如下所示:
http://sqlfiddle.com/#!18/dc3cf/3
| id | tag | child_id |
|---- |----- |---------- |
| 1 | A | |
| 1 | | 4 |
| 2 | C | |
| 3 | C | |
| 4 | B | |
| 4 | | 5 |
| 5 | D | |
| 5 | E | |
每个'id'记录可能有一个child(存储在同一个table中)。每个 child 可以有任意数量的子 children。我不知道层次结构级别的数量,但它可能不会超过 10 个级别。
例子中有:
- 3 个根元素:id 的
1
、2
、3
- 1个child和1个child的child of id
1
:id的4
和5
(分别)
问题
我需要能够查询以获得所有 id 标签的结果,包括它的所有 children 标签。例如,根据上面的 table 数据,我需要输出如下:
| id | tag |
|---- |----- |
| 1 | A |
| 1 | B |
| 1 | D |
| 1 | E |
| 2 | C |
| 3 | C |
| 4 | B |
| 5 | D |
| 5 | E |
请注意,我需要 children 仍然出现。
如果不多次将 table 连接到自身 'n' 中 'n' 是层级数,这是否可能?
编辑
澄清一下,每个id也是一个根元素。因此,了解一个 ID 是否也是 child 的唯一方法是查看该 ID 是否有另一条记录,其中它有一个 child_id。我制作了另一个版本的 SQL Fiddle 来证明这一点。请注意,id 2 现在有一个 child:
http://sqlfiddle.com/#!18/422f9/1
| id | tag | child_id |
|---- |----- |---------- |
| 1 | A | |
| 1 | | 4 |
| 2 | C | |
| 2 | | 5 |
| 3 | C | |
| 4 | B | |
| 4 | | 5 |
| 5 | D | |
| 5 | E | |
是的,不加入tablen次是可以的,可以使用CTE(Common Table Expression),see Docs
在您的情况下,代码应该类似于:
WITH cte (id, tag, child_id, parent) AS
(
SELECT id, tag, child_id, id
FROM demo
WHERE id NOT IN(SELECT child_id FROM demo WHERE child_id IS NOT NULL)
UNION ALL
SELECT demo.id, demo.tag, demo.child_id, cte.parent
FROM demo
JOIN cte
ON cte.child_id = demo.id
)
SELECT parent, tag
FROM cte
WHERE tag IS NOT NULL
UNION
SELECT id, tag
FROM demo
WHERE tag IS NOT NULL
ORDER BY parent, tag
编辑: 动态确定基础元素。
背景
我在 SQL 服务器中有一个数据库架构,如下所示:
http://sqlfiddle.com/#!18/dc3cf/3
| id | tag | child_id |
|---- |----- |---------- |
| 1 | A | |
| 1 | | 4 |
| 2 | C | |
| 3 | C | |
| 4 | B | |
| 4 | | 5 |
| 5 | D | |
| 5 | E | |
每个'id'记录可能有一个child(存储在同一个table中)。每个 child 可以有任意数量的子 children。我不知道层次结构级别的数量,但它可能不会超过 10 个级别。
例子中有:
- 3 个根元素:id 的
1
、2
、3
- 1个child和1个child的child of id
1
:id的4
和5
(分别)
问题
我需要能够查询以获得所有 id 标签的结果,包括它的所有 children 标签。例如,根据上面的 table 数据,我需要输出如下:
| id | tag |
|---- |----- |
| 1 | A |
| 1 | B |
| 1 | D |
| 1 | E |
| 2 | C |
| 3 | C |
| 4 | B |
| 5 | D |
| 5 | E |
请注意,我需要 children 仍然出现。
如果不多次将 table 连接到自身 'n' 中 'n' 是层级数,这是否可能?
编辑
澄清一下,每个id也是一个根元素。因此,了解一个 ID 是否也是 child 的唯一方法是查看该 ID 是否有另一条记录,其中它有一个 child_id。我制作了另一个版本的 SQL Fiddle 来证明这一点。请注意,id 2 现在有一个 child: http://sqlfiddle.com/#!18/422f9/1
| id | tag | child_id |
|---- |----- |---------- |
| 1 | A | |
| 1 | | 4 |
| 2 | C | |
| 2 | | 5 |
| 3 | C | |
| 4 | B | |
| 4 | | 5 |
| 5 | D | |
| 5 | E | |
是的,不加入tablen次是可以的,可以使用CTE(Common Table Expression),see Docs
在您的情况下,代码应该类似于:
WITH cte (id, tag, child_id, parent) AS
(
SELECT id, tag, child_id, id
FROM demo
WHERE id NOT IN(SELECT child_id FROM demo WHERE child_id IS NOT NULL)
UNION ALL
SELECT demo.id, demo.tag, demo.child_id, cte.parent
FROM demo
JOIN cte
ON cte.child_id = demo.id
)
SELECT parent, tag
FROM cte
WHERE tag IS NOT NULL
UNION
SELECT id, tag
FROM demo
WHERE tag IS NOT NULL
ORDER BY parent, tag
编辑: 动态确定基础元素。