WITH RECURSIVE SELECT 通过辅助 table
WITH RECURSIVE SELECT via secondary table
我很难把它拼凑起来。我不擅长数据库或复杂的查询。
数据库
我正在使用最新的 MariaDB 版本。
我有一个数据库table这样的配置,代表一个分层数据结构:
|----------------------|
| fieldsets |
|----+-----------------|
| id | parent_field_id |
|----+-----------------|
| 1 | NULL |
| 2 | 1 |
|----------------------|
|-------------------------|
| fields |
|----+--------------------|
| id | parent_fieldset_id |
|----+--------------------|
| 1 | 1 |
| 2 | 1 |
|-------------------------|
问题
我正在尝试拼凑一个递归查询。我需要 select 给定层次结构中的每个字段集。例如,在上面的 stripped-down 示例中,我想要 select fieldset of id = 1
,以及每个后代 fieldset.
层次结构中任何给定级别的下一个梯级的 ID 只能通过次级 table 的列获得。
table fieldsets
不包含我可以直接获取所有 child fieldsets
的列。我需要获取给定 fieldset
的 child 的所有 fields
,然后获取 field
的 child 的所有 fieldsets
].
更好地说明问题
由于报告的错误,此查询无效:"Restrictions imposed on recursive definitions are violated for table all_fieldsets"
但是,它确实说明了我需要做什么才能获得层次结构中的所有后代 fieldsets
(请记住,字段集不包含其 parent [=19= 的列) ],因为 fieldset
不能将 fieldset
作为直接 parent。相反,fieldset
有一个 parent_field_id
,它指向 [= 中的一行18=] table,fields
table 中的那一行相应地有一个名为 parent_fieldset_id
的列,它指向 fieldsets
[=80] 中的一行=],这被认为是 parent fieldset
到 fieldset
,只是一个间接的 parent.
WITH RECURSIVE all_fieldsets AS (
SELECT fieldsets.* FROM fieldsets WHERE id = 125
UNION ALL
SELECT fieldsets.* FROM fieldsets
WHERE fieldsets.parent_field_id IN (
SELECT id FROM fields f
INNER JOIN all_fieldsets afs
WHERE f.parent_fieldset_id = afs.id
)
)
SELECT * FROM all_fieldsets
我的尝试
到目前为止我的查询(不起作用):
WITH RECURSIVE all_fieldsets AS (
SELECT fieldsets.* FROM fieldsets WHERE id = 125
UNION
SELECT fieldsets.* FROM fieldsets WHERE fieldsets.id IN (SELECT fs.id FROM fieldsets fs LEFT JOIN fields f ON f.id = fs.parent_field_id WHERE f.parent_fieldset_id = fieldsets.id)
)
SELECT * FROM all_fieldsets
我的研究
我也很难找到适合我 use-case 的示例。对于涉及一个 table 仅与自身有关系的层次结构,有很多结果,而不是像我的情况那样通过辅助 table。当您不知道某些概念的正确术语时,这很困难,而且任何外行解释似乎都会产生太多切线搜索结果。
我的请求
我将非常感谢所有能指出我出错的地方,并可能提出可行的查询大纲的人。
我在您当前的代码中看到的主要问题是 CTE 的递归部分(出现在并集之后的查询)没有从递归 CTE 中选择,而它应该是。考虑这个更新版本:
WITH RECURSIVE all_fieldsets AS (
SELECT * FROM fieldsets WHERE id = 125
UNION ALL
SELECT f1.*
FROM fieldsets f1
INNER JOIN all_fieldsets f2
ON f1.parent_field_id = f2.id
)
SELECT *
FROM all_fieldsets;
请注意,CTE 的递归部分中的联接将 fieldsets
中的给定后代记录与其在 CTE 中的父项相关联。
我下班回到家,我就是无法放下它!
但是,从中得出了一个解决方案。
我强烈建议阅读这个关于递归查询的答案,以更好地了解它们的工作原理以及语法的含义。非常精彩的解释:How to select using WITH RECURSIVE clause
解决方案
WITH RECURSIVE all_fieldsets AS (
SELECT * FROM fieldsets fs
WHERE id = 59
UNION ALL
SELECT fs.* FROM fieldsets fs
INNER JOIN all_fieldsets afs
INNER JOIN fields f
ON f.parent_fieldset_id = afs.id
AND fs.parent_field_id = f.id
)
SELECT * FROM all_fieldsets
我不得不使用连接从 fields
table 中获取信息,以便获得层次结构中的下一级,然后递归执行此操作,直到结果为空递归查询。
我很难把它拼凑起来。我不擅长数据库或复杂的查询。
数据库
我正在使用最新的 MariaDB 版本。
我有一个数据库table这样的配置,代表一个分层数据结构:
|----------------------|
| fieldsets |
|----+-----------------|
| id | parent_field_id |
|----+-----------------|
| 1 | NULL |
| 2 | 1 |
|----------------------|
|-------------------------|
| fields |
|----+--------------------|
| id | parent_fieldset_id |
|----+--------------------|
| 1 | 1 |
| 2 | 1 |
|-------------------------|
问题
我正在尝试拼凑一个递归查询。我需要 select 给定层次结构中的每个字段集。例如,在上面的 stripped-down 示例中,我想要 select fieldset of id = 1
,以及每个后代 fieldset.
层次结构中任何给定级别的下一个梯级的 ID 只能通过次级 table 的列获得。
table fieldsets
不包含我可以直接获取所有 child fieldsets
的列。我需要获取给定 fieldset
的 child 的所有 fields
,然后获取 field
的 child 的所有 fieldsets
].
更好地说明问题
由于报告的错误,此查询无效:"Restrictions imposed on recursive definitions are violated for table all_fieldsets"
但是,它确实说明了我需要做什么才能获得层次结构中的所有后代 fieldsets
(请记住,字段集不包含其 parent [=19= 的列) ],因为 fieldset
不能将 fieldset
作为直接 parent。相反,fieldset
有一个 parent_field_id
,它指向 [= 中的一行18=] table,fields
table 中的那一行相应地有一个名为 parent_fieldset_id
的列,它指向 fieldsets
[=80] 中的一行=],这被认为是 parent fieldset
到 fieldset
,只是一个间接的 parent.
WITH RECURSIVE all_fieldsets AS (
SELECT fieldsets.* FROM fieldsets WHERE id = 125
UNION ALL
SELECT fieldsets.* FROM fieldsets
WHERE fieldsets.parent_field_id IN (
SELECT id FROM fields f
INNER JOIN all_fieldsets afs
WHERE f.parent_fieldset_id = afs.id
)
)
SELECT * FROM all_fieldsets
我的尝试
到目前为止我的查询(不起作用):
WITH RECURSIVE all_fieldsets AS (
SELECT fieldsets.* FROM fieldsets WHERE id = 125
UNION
SELECT fieldsets.* FROM fieldsets WHERE fieldsets.id IN (SELECT fs.id FROM fieldsets fs LEFT JOIN fields f ON f.id = fs.parent_field_id WHERE f.parent_fieldset_id = fieldsets.id)
)
SELECT * FROM all_fieldsets
我的研究
我也很难找到适合我 use-case 的示例。对于涉及一个 table 仅与自身有关系的层次结构,有很多结果,而不是像我的情况那样通过辅助 table。当您不知道某些概念的正确术语时,这很困难,而且任何外行解释似乎都会产生太多切线搜索结果。
我的请求
我将非常感谢所有能指出我出错的地方,并可能提出可行的查询大纲的人。
我在您当前的代码中看到的主要问题是 CTE 的递归部分(出现在并集之后的查询)没有从递归 CTE 中选择,而它应该是。考虑这个更新版本:
WITH RECURSIVE all_fieldsets AS (
SELECT * FROM fieldsets WHERE id = 125
UNION ALL
SELECT f1.*
FROM fieldsets f1
INNER JOIN all_fieldsets f2
ON f1.parent_field_id = f2.id
)
SELECT *
FROM all_fieldsets;
请注意,CTE 的递归部分中的联接将 fieldsets
中的给定后代记录与其在 CTE 中的父项相关联。
我下班回到家,我就是无法放下它!
但是,从中得出了一个解决方案。
我强烈建议阅读这个关于递归查询的答案,以更好地了解它们的工作原理以及语法的含义。非常精彩的解释:How to select using WITH RECURSIVE clause
解决方案
WITH RECURSIVE all_fieldsets AS (
SELECT * FROM fieldsets fs
WHERE id = 59
UNION ALL
SELECT fs.* FROM fieldsets fs
INNER JOIN all_fieldsets afs
INNER JOIN fields f
ON f.parent_fieldset_id = afs.id
AND fs.parent_field_id = f.id
)
SELECT * FROM all_fieldsets
我不得不使用连接从 fields
table 中获取信息,以便获得层次结构中的下一级,然后递归执行此操作,直到结果为空递归查询。