MySql中使用递归生成ID序列
我们有一个定义为交易的表 如图所示,id不是连续的。目标是识别丢失的id。我试图首先使用递归生成所有id。然后使用左连接来标识缺少的id。 这里的预期输出应该是3,4,7,11,12,13,14 这是我的方法MySql中使用递归生成ID序列,mysql,sql,subquery,common-table-expression,recursive-query,Mysql,Sql,Subquery,Common Table Expression,Recursive Query,我们有一个定义为交易的表 如图所示,id不是连续的。目标是识别丢失的id。我试图首先使用递归生成所有id。然后使用左连接来标识缺少的id。 这里的预期输出应该是3,4,7,11,12,13,14 这是我的方法 WITH RECURSIVE CTE (id) AS( SELECT MIN(id) FROM transactions UNION ALL SELECT id+1 FROM CTE WHERE id<=(SEL
WITH RECURSIVE CTE (id) AS(
SELECT MIN(id)
FROM transactions
UNION ALL
SELECT id+1
FROM CTE
WHERE id<=(SELECT MAX(id) FROM transactions)
)
SELECT *
FROM CTE;
在事务表中,该数字仅为15。但我得到以下错误
第289行出现错误3636 HY000:递归查询在1001次迭代后中止。尝试将@cte\u max\u recursion\u depth增加到更大的值。请注意MySQL版本是8.0.22。非常感谢您的帮助。您的代码不应引发该错误,如中所示 但是,您可以通过避免递归成员中的子查询来稍微优化查询。这将是:
with recursive cte as (
select min(id) as id, max(id) as max_id from transactions
union all
select id + 1, max_id from cte where id < max_id
)
select c.id
from cte c
where not exists (select 1 from transactions t where t.id = c.id)
然而,这仍然是一种蛮力的方法。如果您有很多行和一些缺失的数字,我们可以通过只生成缺失数字的范围来提高查询效率:
with recursive
data as (
select id, lead(id) over(order by id) lead_id from transactions
),
cte as (
select id + 1 as id, lead_id - 1 as max_id from data where lead_id > id + 1
union all
select id + 1, max_id from cte where id < max_id
)
select id from cte
您的代码不应引发该错误,如中所示 但是,您可以通过避免递归成员中的子查询来稍微优化查询。这将是:
with recursive cte as (
select min(id) as id, max(id) as max_id from transactions
union all
select id + 1, max_id from cte where id < max_id
)
select c.id
from cte c
where not exists (select 1 from transactions t where t.id = c.id)
然而,这仍然是一种蛮力的方法。如果您有很多行和一些缺失的数字,我们可以通过只生成缺失数字的范围来提高查询效率:
with recursive
data as (
select id, lead(id) over(order by id) lead_id from transactions
),
cte as (
select id + 1 as id, lead_id - 1 as max_id from data where lead_id > id + 1
union all
select id + 1, max_id from cte where id < max_id
)
select id from cte
@GMB你的意见有道理。在平台中似乎有一些隐藏的情况超过了递归深度。我想知道,你知道如何增加cte_max_递归深度吗?thanks@jay正如您在mysql中更改任何其他设置一样:通过配置文件或set语句。@GMB感谢您的帮助。我想知道的是一个边缘案例。如果id从非零值开始,例如3。在这种情况下,0,1,2是缺少的值,应该在输出中。是否可以修改上述逻辑以包括这些边缘情况?谢谢@GMB你的意见有道理。在平台中似乎有一些隐藏的情况超过了递归深度。我想知道,你知道如何增加cte_max_递归深度吗?thanks@jay正如您在mysql中更改任何其他设置一样:通过配置文件或set语句。@GMB感谢您的帮助。我想知道的是一个边缘案例。如果id从非零值开始,例如3。在这种情况下,0,1,2是缺少的值,应该在输出中。是否可以修改上述逻辑以包括这些边缘情况?谢谢如果零丢失了怎么办?如果零丢失了怎么办?