sql - SQLite 中的递归 CTE

标签 sql sqlite aggregate-functions common-table-expression recursive-query

我正在尝试学习如何使用 SQL 1999 中引入的公用表表达式来解决通用 Material list 问题。我假设给出下表:

create table part(id int, name string, price int)
create table assembly(part_id int, subpart_id int, quantity int)

装配表中的一行表示一个零件包含子零件的多个实例,而子零件又可能有自己的子零件,依此类推。装配表代表一个结构,一棵树,以给定的part_id作为其根。

我想计算结构中每个部分出现的总次数。

这是我使用公用表表达式的尝试:

WITH RECURSIVE bom(part_id, component_id, total) AS
    (SELECT id, id, 1 FROM part 
        UNION
     SELECT assembly.part_id, bom.component_id, sum(assembly.quantity * bom.total)
     FROM assembly, bom
     WHERE assembly.subpart_id = bom.part_id
     GROUP BY assembly.part_id, bom.component_id)
SELECT component_id, total FROM bom WHERE part_id = root;

在 Mac OS X 10.9.5 上的 SQLite 3.9.1 下,我收到以下错误消息: 错误:第 78 行附近:不支持递归聚合查询

那么,这是 SQLite 限制,还是 SQL 标准限制?

无论哪种情况,任何人都可以建议我如何重写此解决方案以在公用表表达式中积累更多信息,然后在使用结果表的查询中执行聚合?

非常感谢, 罗德尼

最佳答案

这是通过将聚合移至外部查询来解决问题的简单方法:

WITH RECURSIVE bom(part_id, component_id, total) AS
    (SELECT id, id, 1 FROM part 
        UNION ALL
     SELECT assembly.part_id, bom.component_id, assembly.quantity * bom.total
     FROM assembly, bom
     WHERE assembly.subpart_id = bom.part_id)
SELECT component_id, SUM(total) FROM bom 
WHERE part_id = root
GROUP BY component_id;

与最初的尝试相比,此解决方案需要更多的空间和可能更多的时间。

关于sql - SQLite 中的递归 CTE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33227378/

相关文章:

sql - OLEDB 命名参数和分组依据 : "?" won't work

MySQL根据先前的查询结果交织两个查询

sql - SQL 查询中\(反斜杠) 是什么意思?

android - Android 中的多个数据库连接(来自 Activity 和 Service)

sql - try catch 更新单个记录中特定字段的日期和时间

表重命名后,sqlite 模式在表名周围有引号

sql - 根据所选列中的相同值向行添加数字

java - 创建聚合函数在 hsqldb 中不起作用

sql - DISTINCT 有两个 array_agg(或一个 array_agg 里面有元组)?

sql - 为什么 SQLiteStudio(和其他)默认情况下不以人类可读的格式显示日期时间?