mysql - 递归sql查询中的无限循环
问题描述
也许有人会建议我如何解决我的问题。我不知道它为什么会发生以及如何解决它。在我看来,我的 sql 代码不起作用的原因是它变成了不定式循环。我有表:
CREATE TABLE `c_logistics_tran_group3` (
`ltrgr_id` int(10) UNSIGNED NOT NULL,
`ltrgr_lagr_id` int(10) UNSIGNED NOT NULL,
`ltrgr_ltran_id` int(10) UNSIGNED NOT NULL,
`ltrgr_created` timestamp NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ALTER TABLE `c_logistics_tran_group3`
ADD PRIMARY KEY (`ltrgr_id`),
ADD UNIQUE KEY `ltrgr_lagr_id` (`ltrgr_lagr_id`,`ltrgr_ltran_id`),
ADD KEY `c_logistics_tran_group3_ibfk_2` (`ltrgr_ltran_id`);
ALTER TABLE `c_logistics_tran_group3`
MODIFY `ltrgr_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
和数据:
INSERT INTO `c_logistics_tran_group3`
(`ltrgr_id`, `ltrgr_lagr_id`, `ltrgr_ltran_id`, `ltrgr_created`)
VALUES
(2373, 2154, 2312, '2021-09-09 07:54:55'),
(2378, 2154, 2314, '2021-09-09 08:05:25'),
(2382, 2154, 2318, '2021-09-09 10:37:37'),
(2450, 2154, 2386, '2021-09-17 11:44:58'),
(2375, 2156, 2312, '2021-09-09 07:57:14'),
(2380, 2156, 2316, '2021-09-09 10:25:01'),
(2381, 2156, 2317, '2021-09-09 10:37:07'),
(2451, 2156, 2387, '2021-09-17 11:45:37'),
(2376, 2157, 2312, '2021-09-09 08:03:10'),
(2387, 2157, 2323, '2021-09-10 10:36:15'),
(2388, 2157, 2324, '2021-09-10 10:42:59'),
(2449, 2157, 2385, '2021-09-17 11:41:36'),
(2377, 2158, 2312, '2021-09-09 08:04:35');
COMMIT;
我的 sql 代码:
with
recursive
edges as (
select t1.ltrgr_lagr_id as lagr_id1, t2.ltrgr_lagr_id as lagr_id2
from c_logistics_tran_group3 t1
inner join c_logistics_tran_group3 t2 on t2.ltrgr_ltran_id = t1.ltrgr_ltran_id
where 1 = 1
and t1.ltrgr_lagr_id in(2154, 2156, 2157, 2158)
and t2.ltrgr_lagr_id in(2154, 2156, 2157, 2158)
),
cte as (
select lagr_id1, lagr_id2, concat(lagr_id1, ',', lagr_id2) as visited
from edges
union all
select c.lagr_id1, e.lagr_id2, concat(c.visited, ',', e.lagr_id2)
from cte c
inner join edges e on e.lagr_id1 = c.lagr_id2
where not find_in_set(e.lagr_id2, c.visited)
)
select * from cte;
此 SQL 代码执行此处描述的任务: 选择按其值连接的键
如果我从列表中删除任何 lagr_id 一切正常。例如:
and t1.ltrgr_lagr_id in(2154, 2156, 2157)
and t2.ltrgr_lagr_id in(2154, 2156, 2157)
当你在列表中都是 4 lagr_id 时,我的 sql 代码挂断了。只有服务器重启有帮助:(有人对如何解决这个问题有任何想法吗?如何避免我的 sql 代码中的无限循环?MariaDB 版本 10.5.12
解决方案
这不是一个无限循环,但您正在耗尽一些资源。
您可以通过以下方式改进查询:
- 我在子查询中添加
DISTINCT
子句edges
以避免重复行。 - 我在子查询中添加
CASE
语句cte
以避免在visited
列中设置两次相同的值(当 lagr_id1 = lagr_id2 时)。 - 我替换
UNION ALL
为UNION
以避免重复的行。
WITH
RECURSIVE
edges AS (
SELECT DISTINCT t1.ltrgr_lagr_id AS lagr_id1, t2.ltrgr_lagr_id AS lagr_id2
FROM c_logistics_tran_group3 t1
INNER JOIN c_logistics_tran_group3 t2 ON t2.ltrgr_ltran_id = t1.ltrgr_ltran_id
WHERE t1.ltrgr_lagr_id in(2154, 2156, 2157, 2158)
AND t2.ltrgr_lagr_id in(2154, 2156, 2157, 2158)
),
cte AS (
SELECT lagr_id1, lagr_id2, CASE WHEN lagr_id1 = lagr_id2 THEN lagr_id1 ELSE concat(lagr_id1, ',', lagr_id2) END AS visited
FROM edges
UNION
SELECT c.lagr_id1, e.lagr_id2, concat(c.visited, ',', e.lagr_id2)
FROM cte c
INNER JOIN edges e ON e.lagr_id1 = c.lagr_id2
WHERE NOT find_in_set(e.lagr_id2, c.visited)
)
SELECT * FROM cte;
行数大幅减少,但我认为我的查询可以改进,例如visited
值'2154,2156,2158,2157'与'2154,2156,2157,2158'相同,因为组合的顺序不是在结果中很重要,因此查询应该丢弃其中之一。
推荐阅读
- javascript - 从字符串中获取html代码并以角度显示
- python - 如何从包含 nan 的熊猫数据框中删除行
- python - 文本提取:退出代码 127 失败 // windows 10 // pdftotext
- python - 如何在python中匹配多个单词
- css - 在 Hugo Academic 中购买的字体未在所有现代浏览器/计算机上显示
- reactjs - 在 StackOverFlow 代码片段中使用 React Hook
- c - 返回带有错误文件描述符的系统调用不是负数
- python - 如何从这样的链接下载文件?
- angular - 无法从 Dialog Flow 访问客户端访问令牌,我需要在 Angular 应用程序中使用
- android - 将新屏幕推送到堆栈时,Android 上的从左到右动画与 react-native-navigation