首/尾(聚合)
来自 PostgreSQL wiki
跳转到导航跳转到搜索此聚合函数返回每个组中第一个或最后一个输入行的值,忽略 NULL 行。(NULL 会被 STRICT
声明自动忽略,此处有说明)
结果取决于输入行的排序顺序,对于未排序的输入,排序顺序是任意的。
函数和聚合函数可以在 Postgres 9.6 或更高版本中为 PARALLEL SAFE
。当聚合函数与 ORDER BY
一起使用时,永远不会使用并行处理。手册:
当前不支持有序集聚合的局部(包括并行)聚合。此外,它永远不会用于包含
DISTINCT
或ORDER BY
子句的聚合调用,因为这些语义在局部聚合期间无法得到支持。
对于未排序的输入,聚合函数返回一个任意结果(可能使用并行处理),对于已排序的输入,返回一个确定性结果(不使用并行处理)。
示例
test=# select first(column1), last(column1) from (values (null),(1),(3),(null)) as x; first | last -------+------ 1 | 3
SQL 版本
这是一个没有外部依赖关系的 SQL 语言实现。
-- Create a function that always returns the first non-NULL value:
CREATE OR REPLACE FUNCTION public.first_agg (anyelement, anyelement)
RETURNS anyelement
LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE AS
'SELECT $1';
-- Then wrap an aggregate around it:
CREATE AGGREGATE public.first (anyelement) (
SFUNC = public.first_agg
, STYPE = anyelement
, PARALLEL = safe
);
-- Create a function that always returns the last non-NULL value:
CREATE OR REPLACE FUNCTION public.last_agg (anyelement, anyelement)
RETURNS anyelement
LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE AS
'SELECT $2';
-- Then wrap an aggregate around it:
CREATE AGGREGATE public.last (anyelement) (
SFUNC = public.last_agg
, STYPE = anyelement
, PARALLEL = safe
);
最初的想法:http://archives.postgresql.org/pgsql-hackers/2006-03/msg01324.php,并做了一些修正。
快速 C 版本
一个用 C 编写的更快的版本可在 PGXN 中获得,名为 first_last_agg:http://pgxn.org/dist/first_last_agg/