假设我在 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
当没有对查询或聚合函数内显式施加排序时,可以安全地假设多个列的排序将保持一致吗?
通常,输入行以未指定的顺序馈送到聚合函数。[...]
但是,某些聚合函数(例如array_agg和 string_agg)生成的结果取决于输入行的顺序。当使用这样的聚合时,可选的order_by_clause 可用于指定所需的 ordering。
我的理解是:除非您使用ORDER BY
.