sqlite递归查询指定搜索顺序的方法

原文地址

使用 ORDER BY 控制树的深度优先与广度优先搜索

在递归选择的 ORDER BY 子句可用于控制对树的搜索是深度优先还是广度优先。为了说明这一点,我们将使用前面示例中 "org" 表的一个变体,其中不包含 "height" 列,并插入一些实际数据:

sql 复制代码
CREATE TABLE org(
  name TEXT PRIMARY KEY,
  boss TEXT REFERENCES org
) WITHOUT ROWID;
INSERT INTO org VALUES('Alice',NULL);
INSERT INTO org VALUES('Bob','Alice');
INSERT INTO org VALUES('Cindy','Alice');
INSERT INTO org VALUES('Dave','Bob');
INSERT INTO org VALUES('Emma','Bob');
INSERT INTO org VALUES('Fred','Cindy');
INSERT INTO org VALUES('Gail','Cindy');

以下是一个以广度优先模式展示树结构的查询:

sql 复制代码
WITH RECURSIVE
  under_alice(name,level) AS (
    VALUES('Alice',0)
    UNION ALL
    SELECT org.name, under_alice.level+1
      FROM org JOIN under_alice ON org.boss=under_alice.name
     ORDER BY 2
  )
SELECT substr('..........',1,level*3) || name FROM under_alice;

"ORDER BY 2"(与 "ORDER BY under_alice.level+1" 含义相同)会使组织结构图中较高的层级(具有较小的 "level" 值)被优先处理,从而实现广度优先搜索。输出结果如下:

复制代码
Alice
...Bob
...Cindy
......Dave
......Emma
......Fred
......Gail

但是,如果我们在 ORDER BY 子句中添加 "DESC" 修饰符,这将使组织结构中较低的层级(具有较大的 "level" 值)在递归选择中被优先处理,从而实现深度优先搜索:

sql 复制代码
WITH RECURSIVE
  under_alice(name,level) AS (
    VALUES('Alice',0)
    UNION ALL
    SELECT org.name, under_alice.level+1
      FROM org JOIN under_alice ON org.boss=under_alice.name
     ORDER BY 2 DESC
  )
SELECT substr('..........',1,level*3) || name FROM under_alice;

修改后的查询输出为:

复制代码
Alice
...Bob
......Dave
......Emma
...Cindy
......Fred
......Gail

注意 :当递归选择中省略 ORDER BY 子句时,队列的行为类似于 FIFO(先进先出),从而实现广度优先搜索。

相关推荐
盛世宏博北京2 小时前
守护千年文脉:图书馆古籍库房自动化环境治理(温湿度 + 消毒)技术方案
服务器·数据库·自动化·图书馆温湿度监控
「光与松果」2 小时前
Mongodb 日常维护命令集
数据库·mongodb
哥哥还在IT中2 小时前
etcd内存占用高如何排查
数据库·etcd
Web极客码2 小时前
使用phpMyAdmin轻松操作WordPress数据库
数据库·oracle
啥都不懂的小小白2 小时前
MVCC深度解析:MySQL如何实现高效无阻塞的并发读写
数据库·mysql·mvcc
程序员根根2 小时前
MySQL 事务全解析:从 ACID 特性到实战落地(部门 - 员工场景)
数据库·后端
爱吃山竹的大肚肚2 小时前
MySQL 支持的各类索引
java·数据库·sql·mysql·spring·spring cloud
黑白极客2 小时前
mysql的 order by是怎么工作的?redo-log和binlog为什么采用双确认机制?
数据库·mysql
程序员水自流2 小时前
MySQL常用内置函数详细介绍
java·数据库·mysql