【发布时间】:2013-08-24 12:34:45
【问题描述】:
给定以下 PostgreSQL 表:
items
integer id
integer parent_id
string name
unique key on [parent_id, name]
parent_id is null for all root nodes
目前我手动构建 sql 查询,对每个路径元素进行连接。但这对我来说似乎很丑陋,当然它限制了可能的深度。
例子:
path: holiday,images,spain
SELECT i3.*
FROM items AS i1
, items AS i2
, items AS i3
WHERE i1.parent_id IS NULL AND i1.name = 'holiday'
AND i2.parent_id=i1.id AND i2.name = 'images'
AND i3.parent_id=i2.id AND i3.name = 'spain'
我想知道是否有更好的方法,可能使用 CTE?
你可以在这里看到我当前的代码是如何工作的以及预期的输出是什么:
http://sqlfiddle.com/#!1/4537c/2
【问题讨论】:
-
问题不是很清楚。什么是“最后一个节点”?如果您已经拥有“完整路径”,您需要搜索什么?您的表定义也不是很有帮助。也许在问题中添加一些示例数据?
-
额外问题:1) i1 之上是否还有其他 unmatched 节点?在 i1 和 i2 之间,在 i2 和 i3 之间?低于 i3 ?如果是这样:您是否也希望检索这些内容? 2) 路径中 {holiday,images,spain} 的 order 是否重要,或者这些是否可以按任何顺序出现?顺便说一句:
parent_id上的唯一索引是不可能的(而且是错误的) -
我刚刚添加了一个 sqlfiddle。最后一个节点是路径的最后一项 (a,b,c,d -> d)。我只有名字,没有id。节点的名称不是全局唯一的,这就是我必须检查所有父母的原因。我现在正在使用连接来执行此操作,但是连接的数量等于路径元素的数量。哪个不好。
-
在我的查询中,i1 始终是根节点,因为 parent_id 为空。补丁是完整的,所以没有丢失的元素。我只需要最后一个节点(id 就足够了)。路径元素的顺序很重要。将其视为文件系统的目录结构。
标签: sql postgresql common-table-expression recursive-cte