存在循环引用的递归 CTE [英] Recursive CTE in presence of circular references

查看:43
本文介绍了存在循环引用的递归 CTE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 SQL Server 数据库中有一个层次结构.我正在尝试编写一个查询来获取给定元素下结构中的所有元素.

I have a hierarchical structure in a SQL Server database. I'm trying to write a query to get all elements in the structure under a given element.

所以,给定一个包含 id 和 parent_id 列的数据库表,这就是我所做的:

So, given a DB table with the columns id and parent_id, this is what I do:

WITH recursive_cte (root_id, id) AS (
  SELECT parent_id, id
  FROM test_cte
  UNION ALL
  SELECT t.parent_id, r.id
  FROM test_cte t
  INNER JOIN recursive_cte r
  ON (r.root_id=t.id)
)
SELECT *
FROM recursive_cte
WHERE root_id=0

现在,如果在 id=0 元素下的结构中有循环引用,我会从 DBMS 收到错误消息(最大递归 100 在语句完成之前已用完).这很好,循环引用的存在已经是一个错误.

Now, if there is a circular reference in the structure under the element with id=0 I get an error from the DBMS (The maximum recursion 100 has been exhausted before statement completion). This is fine, the existance of circular references is already an error.

但是如果我在另一个元素下的结构中有循环引用,查询总是会报错.即使我指定了将记录集限制为非循环记录的条件(例如 WHERE root_id=0).

But if I have a circular reference in the structure under another element, the query will always give an error. Even if I specify a condition which restricts the record set to a non circular one (e.g WHERE root_id=0).

例如:

id|parent_id|name           |
--+---------+---------------+
0 |NULL     |TEST A         |
1 |4        |TEST CIRCULAR  |
2 |0        |TEST B         |
3 |2        |TEST C         |
4 |1        |TEST CIRCULAR B|

我希望我的查询在条件 root_id=0 的情况下正常工作而不会出错.有没有办法做到这一点?

I want my query to work without errors with the condition root_id=0. Is there a way to do that?

推荐答案

您需要将 WHERE 过滤器放在查询的 CTE 部分,如下所示:

You will need to put your WHERE-filter in the CTE part of your query, like so:

WITH recursive_cte (root_id, id) AS (
  SELECT parent_id, id
  FROM test_cte
  WHERE id=0       -- Restrict your recursion to start from the item with id = 0, instead of considdering all items.
  UNION ALL
  SELECT t.parent_id, r.id
  FROM test_cte t
  INNER JOIN recursive_cte r
  ON (r.root_id=t.id)
)
SELECT *
FROM recursive_cte

这篇关于存在循环引用的递归 CTE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆