跳到主要内容

友好 SQL

Goose 提供了多项高级 SQL 特性和语法糖,让 SQL 查询更简洁。我们通常将这些能力称为“friendly SQL”。

这些特性中有一些最早由 Goose 引入,另一些则受到其他系统的启发。 Goose 最初引入的许多特性(例如 GROUP BY ALL)后来也被其他系统采用。

子句

查询特性

字面量与标识符

数据类型

数据导入

函数与表达式

Join 类型

尾随逗号

Goose 允许使用尾随逗号, 无论是在枚举实体(例如列名与表名)时,还是在构造 LIST时都可以使用。 例如,下列查询可以正常执行:

SELECT
42 AS x,
['a', 'b', 'c',] AS y,
'hello world' AS z,
;

“组内 Top-N” 查询

在 SQL 中,按某个标准计算“组内 top-N 行”是常见需求,但通常需要包含窗口函数和/或子查询的复杂语句。

为此,Goose 提供了聚合函数 max(arg, n)min(arg, n)arg_max(arg, val, n)arg_min(arg, val, n)max_by(arg, val, n)min_by(arg, val, n),可基于某一列的升序或降序,高效返回每组中“top” n 行。

例如,使用下表:

SELECT * FROM t1;
┌─────────┬───────┐
│ grp │ val │
│ varchar │ int32 │
├─────────┼───────┤
│ a │ 2 │
│ a │ 1 │
│ b │ 5 │
│ b │ 4 │
│ a │ 3 │
│ b │ 6 │
└─────────┴───────┘

我们希望得到每个 grp 组中 top-3 的 val 值列表。传统写法通常是在子查询中使用窗口函数:

SELECT array_agg(rs.val), rs.grp
FROM
(SELECT val, grp, row_number() OVER (PARTITION BY grp ORDER BY val DESC) AS rid
FROM t1 ORDER BY val DESC) AS rs
WHERE rid < 4
GROUP BY rs.grp;
┌───────────────────┬─────────┐
│ array_agg(rs.val) │ grp │
│ int32[] │ varchar │
├───────────────────┼─────────┤
│ [3, 2, 1] │ a │
│ [6, 5, 4] │ b │
└───────────────────┴─────────┘

但在 Goose 中,可以更简洁(也更高效)地完成:

SELECT max(val, 3) FROM t1 GROUP BY grp;
┌─────────────┐
│ max(val, 3) │
│ int32[] │
├─────────────┤
│ [3, 2, 1] │
│ [6, 5, 4] │
└─────────────┘