在duckdb 递归CTE中实现深度优先搜索DFS

原帖地址 https://github.com/duckdb/duckdb/discussions/15386

通常的递归CTE都是广度优先搜索(BFS)

sql 复制代码
WITH RECURSIVE 
edges(a, b) as(
VALUES
  (1, 2),
  (1, 3),
  (2, 4),
  (4, 5),
  (4, 6)
), 
bfs(node, path) AS (
  SELECT 1 AS node, [] :: STRUCT("from" INT, "to" INT)[] AS path -- Start with node 1 (root)
  UNION ALL
  SELECT e.b, bft.path|| [{'from': bft.node, 'to': e.b}]  
  FROM   bfs AS bft,
         edges AS e
  WHERE  bft.node = e.a
)
SELECT * FROM bfs;

┌───────┬────────────────────────────────────────────────────────────────────┐
│ node  │                                path                                │
│ int32 │               struct("from" integer, "to" integer)[]               │
├───────┼────────────────────────────────────────────────────────────────────┤
│     1 │ []                                                                 │
│     2 │ [{'from': 1, 'to': 2}]                                             │
│     3 │ [{'from': 1, 'to': 3}]                                             │
│     4 │ [{'from': 1, 'to': 2}, {'from': 2, 'to': 4}]                       │
│     5 │ [{'from': 1, 'to': 2}, {'from': 2, 'to': 4}, {'from': 4, 'to': 5}] │
│     6 │ [{'from': 1, 'to': 2}, {'from': 2, 'to': 4}, {'from': 4, 'to': 6}] │
└───────┴────────────────────────────────────────────────────────────────────┘

DuckDB CTE模块的设计者kryonix提供了如下技巧提供DFS,但是还有问题,没有求出全部路径。

sql 复制代码
WITH RECURSIVE 
edges(a, b) as(
VALUES
  (1, 2),
  (1, 3),
  (2, 4),
  (4, 5),
  (4, 6)
), 
dfs(stack, path) AS (
  SELECT [1] AS stack, [] :: STRUCT("from" INT, "to" INT)[] AS path -- Start with node 1 (root)
    UNION ALL
  (WITH siblings AS (
    SELECT ARRAY_AGG(e.b ORDER BY e.b ASC) AS siblings
    --                                ^^^
    -- This determines the order of traversal of the siblings
    FROM   dfs AS dft,
           edges AS e
    WHERE  dft.stack[1] = e.a
  )
  SELECT x.*
  FROM   siblings AS _(s), LATERAL
         (SELECT s || dft.stack[2:] AS stack, -- Push the stack
                 dft.path || [{'from': dft.stack[1], 'to': s[1]}] AS path -- Add the edge to the path
          FROM   dfs AS dft
          WHERE  array_length(s) > 0 -- There are more siblings to traverse
            UNION ALL
          SELECT dft.stack[2:], -- Pop the stack
                 [] :: STRUCT("from" INT, "to" INT)[] AS path -- Reset the path
          FROM   dfs AS dft
          WHERE  array_length(s) IS NULL AND dft.stack <> [] -- No more siblings to traverse
          ) AS x
  )
)
SELECT * FROM dfs;

┌───────────┬────────────────────────────────────────────────────────────────────┐
│   stack   │                                path                                │
│  int32[]  │               struct("from" integer, "to" integer)[]               │
├───────────┼────────────────────────────────────────────────────────────────────┤
│ [1]       │ []                                                                 │
│ [2, 3]    │ [{'from': 1, 'to': 2}]                                             │
│ [4, 3]    │ [{'from': 1, 'to': 2}, {'from': 2, 'to': 4}]                       │
│ [5, 6, 3] │ [{'from': 1, 'to': 2}, {'from': 2, 'to': 4}, {'from': 4, 'to': 5}] │
│ [6, 3]    │ []                                                                 │
│ [3]       │ []                                                                 │
│ []        │ []                                                                 │
└───────────┴────────────────────────────────────────────────────────────────────┘
相关推荐
【心态好不摆烂】5 小时前
数据结构基础精讲3
数据结构·算法
漂流瓶jz7 小时前
UVA-1613 K度图的着色 题解答案代码 算法竞赛入门经典第二版
算法·深度优先·图论·贪心·aoapc·算法竞赛入门经典·uva
乌暮7 小时前
Spring AOP 与 Spring 事务:用大白话彻底理解原理与实践
java·数据库·spring boot·后端·sql·学习·spring
Pniubi7 小时前
动态规划入门 ( - 力扣509斐波那契数)
算法·动态规划
吴长建先生重名了8 小时前
GitHub Actions部署报表系统踩坑记:幂等性与限
算法
贝壳6909 小时前
一个2026年2月才上传的库,凭什么敢碰2009年就有人写烂的题目
算法
贝壳6909 小时前
同一道三亿位选型题,三个AI给了我三个答案,我把它们拉进同一台机器复跑
算法
青少儿编程课堂12 小时前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会图形化考级:校园大富翁经营闯关解析
c++·python·算法·bfs·信息学竞赛
在所不辞兄12 小时前
为什么在新能源汽车电驱与热管理开发中,AI驱动的数字孪生和数据驱动仿真正在部分替代对物理台架与实车标定的依赖?
人工智能·深度学习·神经网络·算法·机器学习
AllData公司负责人20 小时前
AI大模型数据开发底座系列说明书,AllData集成Chat2DB开源项目建设AI 数据库分析底座,涵盖AI 洞察/对话SQL/智能视图!
数据库·人工智能·sql·开源·ai 洞察·对话sql