在 Postgres 中订购 WITH RECURSIVE 查询

Posted

技术标签:

【中文标题】在 Postgres 中订购 WITH RECURSIVE 查询【英文标题】:Ordering a WITH RECURSIVE query in Postgres 【发布时间】:2011-03-14 19:00:38 【问题描述】:

我正在 Postgres 中执行递归查询以检索电子邮件列表及其线程子项,如下所示:

WITH RECURSIVE cte (id, title, path, parent_id, depth)  AS (
  SELECT  id, 
          title,
          array[id] AS path,
          parent_id, 
          1 AS depth
  FROM    emails
  WHERE   parent_id IS NULL

  UNION ALL

  SELECT  emails.id,
          emails.title,
          cte.path || emails.id,
          emails.parent_id, 
          cte.depth + 1 AS depth
  FROM    emails
          JOIN cte ON emails.parent_id = cte.id
)
SELECT id, title, path, parent_id, depth FROM cte
ORDER BY path;

在查找子电子邮件之前如何更改列表的顺序(例如按标题排序)。我显然需要保留外部 ORDER BY 以便按树顺序检索列表,并且 Postgres 不会让我在 UNION ALL 之前插入 ORDER BY 子句。

谢谢,

【问题讨论】:

【参考方案1】:

这是未经测试的,但通常我可以在联合之前添加任何 ORDER BY,只要有括号...

WITH RECURSIVE cte (id, title, path, parent_id, depth)  AS (
(  SELECT  id, 
          title,
          array[id] AS path,
          parent_id, 
          1 AS depth
  FROM    emails
  WHERE   parent_id IS NULL
  ORDER BY title
)
  UNION ALL

  SELECT  emails.id,
          emails.title,
          cte.path || emails.id,
          emails.parent_id, 
          cte.depth + 1 AS depth
  FROM    emails
          JOIN cte ON emails.parent_id = cte.id
)
SELECT id, title, path, parent_id, depth FROM cte
ORDER BY path;

【讨论】:

【参考方案2】:

创建一个由查询的第一部分组成的视图,按标题排序。也许是这样的?

      CREATE VIEW title_Sort AS
      SELECT  id,  
      title, 
      array[id] AS path, 
      parent_id,  
      1 AS depth  
      FROM    emails 
      WHERE   parent_id IS NULL 
      ORDER BY title;

然后像以前一样将所有视图与您的其他查询合并。我认为这会奏效。现在在我的上网本上,所以我无法测试:/

【讨论】:

不幸的是,这不起作用。您的方法允许我在第一个查询中执行 ORDER BY,但最后的 ORDER BY 路径将始终取代它 - 结果是列表本质上是按 id 排序的。 嗯,那我不确定你在问什么……最终的 ORDER BY 总是会导致结果表按路径排序。您需要在查询中订购什么?你想做什么取决于订单? 我想检索一个线程电子邮件列表,维护它们的树结构 - 上面的查询允许我这样做 - 并且能够按标题对***项目进行排序。 使用嵌套查询比尝试使用两个 ORDER BY 语句更好...查看这个链接,也许它会帮助你完成你正在寻找的东西(它是 mysql,但是你会明白的):drupal.org/node/555518

以上是关于在 Postgres 中订购 WITH RECURSIVE 查询的主要内容,如果未能解决你的问题,请参考以下文章

Laravel QueryBuilder 中的 Postgres 函数 WITH

Clojure - recur 适用于循环或 let 语句?

使用group by with order一起查询时间慢

Sequelize Postgres createdAt time with timezone,以格式保存和获取日期和时间

Multi-tenant web apps with ASP.NET Core and Postgres

Chat with Milvus #12 :新版本Postgres向量检索插件比Faiss好用?