在一个递归公共表表达式里,递归表用CTE表名命名。在上面的递归公共表表达式示意图中,递归表必须且只能出现在递归查询的FROM子句里,不能
出现在initial-select或者the recursive-select,包括subqueries的任何地方。
初始查询可以是一个联合查询,但是它不能包含ORDER BY, LIMIT, OFFSET.
递归查询必须是一个简单查询,而不能是一个联合查询语句。递归查询允许包含ORDER BY, LIMIT, OFFSET.
执行递归查询表内容的基本算法如下:
1.执行初始查询并将查询结果放入一个队列;
2.如果队列不为空
1.从队列中提取一条记录;
2.将这条记录插入递归表;
3.假设刚刚被提取的记录是递归表中唯一一条记录,然后,运行递归查询,把所有结果放入队列
以上,基本过程可能被以下附加规则修改:
如果,用一个UNION操作符把初始查询和递归查询衔接起来,那么,仅仅当这条记录不在队列时,才将这条记录添加到队列中。重复的记录被丢弃,在加入队列之前。
即使在递归查询时,重复的队列已经从队列中提取出来,如果,操作符是UNION ALL,那么在初始查询和递归查询阶段产生的记录总是被添加到队列当中,即使他们存在重复。
判断记录是否重复,NULL值与另一个NULL值比较是相等的,和其他值比较是不相等的。
LIMIT子句,如果出现,判断递归表中记录的个数,一旦达到指定记录个数,递归停止。一个以0作为限制数值意味阒没有记录被添加到递归表。
一个负值意味着添加到递归表的记录个数是没有限制的。
OFFSET子句,如果出现,有一个正值N, 会阻止前N条记录添加到递归表中。前N条记录仍然被递归查询处理。只是他们不添加到递归表中。当所有OFFSET记录被跳过,才开始记录
记录个数,直到达到限制数值。
如果有ORDER BY子句出现,它会在步骤2a中,决定队列中记录被提取的顺序,如果没有ORDER BY, 那么在被提取的记录顺序是未定义的。在当前实现中,如果省略ORDER BY子句,队列是一个先进先出队列。
但是应用程序不应该依赖这一个事实,因为它可能会改变。
递归查询示例:
以下查询返回1到1000000之间的所有整数。
with recursive
cnt(x) as (values(1) union all select x+1 from cnt where x < 1000000 br style='font-size:16px;font-style:normal;font-weight:normal;color:rgb(0, 0, 0);' /> select * from cnt;
思考这个查询是如何工作的,
初始查询首先运行和返回一个单一字段的单一记录1,这条记录被添加到队列中。
在步骤2a中,这条记录从队列中移
sqlite3-树形递归查询-with
最新推荐文章于 2024-06-04 16:52:00 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)