对于许多操作,DuckDB保留了行的顺序,类似于Pandas等数据框库。
Example
以下表为例:
CREATE TABLE tbl AS
SELECT *
FROM (VALUES (1, 'a'), (2, 'b'), (3, 'c')) t(x, y);
SELECT *
FROM tbl;
| x | y |
|---|---|
| 1 | a |
| 2 | b |
| 3 | c |
让我们来看以下查询,它返回x为奇数的行:
SELECT *
FROM tbl
WHERE x % 2 == 1;
| x | y |
|---|---|
| 1 | a |
| 3 | c |
因为行 (1, 'a') 在原表中出现在 (3, 'c') 之前,所以在这个表中也保证会出现在该行之前。
Clauses
以下子句保证原始行顺序得以保留:
COPY(参见 插入顺序)FROM使用单个表LIMITOFFSETSELECTUNION ALLWHERE- 带有空
OVER子句的窗口函数 - 只要它们仅包含上述组件,公共表表达式和表子查询
提示
row_number() OVER ()允许将原始行顺序转换为一个显式列,可以在默认不保留行顺序的操作中引用。在物化表上,可以使用rowid伪列达到相同的效果。
以下操作不保证行顺序被保留:
FROM带有多个表和/或子查询JOINUNIONUSING SAMPLEGROUP BY(特别是,输出顺序是未定义的,并且除非在聚合函数中明确指定,否则行被输入到order-sensitive aggregate functions的顺序也是未定义的)ORDER BY(特别是,ORDER BY可能不会使用 稳定算法)- 标量子查询
插入顺序
默认情况下,以下组件保留插入顺序:
- CSV 读取器 (
read_csv函数) - JSON 阅读器 (
read_json函数) - Parquet 读取器 (
read_parquet函数)
插入顺序的保留由preserve_insertion_order 配置选项控制。
此设置默认为true,表示应保留顺序。
要更改此设置,请使用:
SET preserve_insertion_order = false;