跳到主要内容

顺序保留

对于许多操作,Goose 会保留行顺序,这一点与 Pandas 等数据框库类似。

示例

以下表为例:

CREATE TABLE tbl AS
SELECT *
FROM (VALUES (1, 'a'), (2, 'b'), (3, 'c')) t(x, y);

SELECT *
FROM tbl;
xy
1a
2b
3c

再看下面这个查询,它会返回 x 为奇数的行:

SELECT *
FROM tbl
WHERE x % 2 == 1;
xy
1a
3c

由于在原始表中行 (1, 'a') 出现在 (3, 'c') 之前,因此在这个结果表中它也保证排在前面。

子句

以下子句可以保证保留原始行顺序:

  • COPY(参见插入顺序
  • 仅包含单个表的 FROM
  • LIMIT
  • OFFSET
  • SELECT
  • UNION ALL
  • WHERE
  • OVER 子句为空的窗口函数
  • 只包含上述组件的公用表表达式与表子查询

提示:row_number() OVER () 可以将原始行顺序转换为显式列,从而在默认不保序的操作中引用该顺序。对于已物化的表,也可以使用 rowid 伪列实现同样效果。

以下操作保证保留行顺序:

  • 包含多个表和/或子查询的 FROM
  • JOIN
  • UNION
  • USING SAMPLE
  • 整表聚合(输入顺序,即行传入对顺序敏感的聚合函数的顺序,除非在聚合函数中显式指定,否则不保证)
  • GROUP BY(输入顺序和输出顺序都不保证)
  • ORDER BY(具体来说,ORDER BY 可能不会使用稳定算法
  • 标量子查询

插入顺序

默认情况下,以下组件会保留插入顺序:

是否保留插入顺序由 preserve_insertion_order 配置项控制。 该设置默认值为 true,表示应保留顺序。 如需更改该设置,请使用:

SET preserve_insertion_order = false;