array_agg 保证 Postgres 中多个列的一致性?

Ste*_*man 7 postgresql

假设我在 Postgres 9.4 中有下表:

 a | b 
---+---
 1 | 2
 3 | 1
 2 | 3
 1 | 1
Run Code Online (Sandbox Code Playgroud)

如果我跑

 select array_agg(a) as a_agg, array_agg(b) as b_agg from foo
Run Code Online (Sandbox Code Playgroud)

我得到我想要的

   a_agg   |   b_agg   
-----------+-----------
 {1,3,2,1} | {2,1,3,1}
Run Code Online (Sandbox Code Playgroud)

两个数组的顺序是一致的:每个数组的第一个元素来自同一行,第二个和第三个也是如此。我实际上并不关心数组的顺序,只关心它们在列之间保持一致。

这似乎很自然地“就这样发生了”,而且似乎确实如此。但它可靠吗?通常,除非指定 ORDER BY 子句,否则 SQL 事物的顺序是未定义的。完全有可能让 postgres 生成不一致的配对,其中包含不一致的 ORDER BY 子句array_agg(需要一些明显适得其反的额外工作):

select array_agg(a order by b) as agg_a, array_agg(b order by a) as agg_b from foo;
Run Code Online (Sandbox Code Playgroud)

产量

   agg_a   |   agg_b   
-----------+-----------
 {3,1,1,2} | {2,1,3,1}
Run Code Online (Sandbox Code Playgroud)

这不再一致。第一个数组元素 3 和 2 并非来自同一原始行。

我想确定的是,如果没有任何 ORDER BY 子句,事情就会自然发生。即使对任一列进行排序,由于重复的元素,仍会存在歧义。我宁愿避免强加明确的排序,因为在我的实际应用程序中,表会很大并且排序可能会很昂贵。但我找不到任何文件可以保证或指定,如果没有强制执行不一致的顺序,多个array_agg调用将按一致的顺序排序,即使如果不是的话,那将是非常令人惊讶的。

array_agg当没有对查询或聚合函数内显式施加排序时,可以安全地假设多个列的排序将保持一致吗?

Con*_*rer 1

根据PostgreSQL 文档

通常,输入行以未指定的顺序馈送到聚合函数。[...]

但是,某些聚合函数(例如array_agg和 string_agg)生成的结果取决于输入行的顺序。当使用这样的聚合时,可选的order_by_clause 可用于指定所需的 ordering

我的理解是:除非使用ORDER BY.