首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在postgres中递归查询中的Order

问在postgres中递归查询中的Order
EN

Stack Overflow用户
提问于 2017-07-11 21:13:17
回答 1查看 2.1K关注 0票数 1

我有以下查询:

代码语言:javascript
复制
with recursive chain(id, weight, depth) as (
select rpCore.itemID2, rpCore.weight, 1 as depth from relations rpCore where itemID1 = 1048663
union 
select r.itemID2, c.weight + r.weight, c.depth + 1from chain c
inner join relations r
on (r.itemID1=id)
where c.depth < 3
order by c.weight + r.weight asc limit 10
) select * from chain order by weight asc limit 10;

如果运行它,将得到以下错误:

代码语言:javascript
复制
ERROR: ORDER BY in a recursive query is not implemented
SQL state: 0A000
Character: 313

由于权重的结构方式(都是正的,并加在一起),如果我能够使查询的递归部分对自身进行排序和限制,查询的外部部分将返回我需要的结果,但似乎不能按递归查询的递归部分执行顺序。

有什么方法来模拟这种行为吗?如果删除限制语句,则查询将运行,但由于有大量行(由于最后的限制语句而没有必要),查询运行得非常慢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-11 22:46:13

正如我理解您的问题一样,您希望为递归CTE关系添加一个限制,以防止它在过多的结果上递归,这会使查询变得缓慢。

答案是你不能这么做。这不仅是因为它没有在PostgreSQL中实现,而且是因为您所要求的内容在逻辑上是不可能的。

当PostgreSQL在每一组相关记录上递归时,它累积了一组事实上按深度排列的集合。这不是您想要的顺序,这是由一个不相关的列,“权重”。因此,Postgres无法在不先积累完整递归数据集的情况下根据权重进行限制。因此,即使支持CTE中的ORDER语句,它也不会提高您的性能。

我还将指出,在任何UNION查询中,ORDER应用于结果数据集,而不是应用于UNION的每个部分。因此,不能仅将其应用于“递归部分”。

当然,您可以像在此查询中已经完成的那样,提前深度终止递归。将UNION改为UNION ALL也将提高性能。

从语法上讲,只需添加第二个CTE即可实现所需的内容:

代码语言:javascript
复制
  with recursive chain(id, weight, depth) as (
  select rpCore.itemID2, rpCore.weight, 1 as depth 
  from relations rpCore 
  where itemID1 = 1048663
  union all
  select r.itemID2, c.weight + r.weight, c.depth + 1
  from chain c
  inner join relations r
  on (r.itemID1=id)
  where c.depth < 3
  ),
  chain_limit as (
  SELECT * FROM chain
  ORDER BY weight LIMIT 10
  )
  select * from chain_limit;

然而,这并不能帮助您实现性能目标。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45044550

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档