在 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 语句?
Sequelize Postgres createdAt time with timezone,以格式保存和获取日期和时间