首/尾(聚合)

来自 PostgreSQL wiki
跳转到导航跳转到搜索

库代码片段

首(聚合)

适用于 PostgreSQL

任何版本

SQL

依赖于

此聚合函数返回每个组中第一个或最后一个输入行的值,忽略 NULL 行。(NULL 会被 STRICT 声明自动忽略,此处有说明

结果取决于输入行的排序顺序,对于未排序的输入,排序顺序是任意的。
函数和聚合函数可以在 Postgres 9.6 或更高版本中为 PARALLEL SAFE。当聚合函数与 ORDER BY 一起使用时,永远不会使用并行处理。手册:

当前不支持有序集聚合的局部(包括并行)聚合。此外,它永远不会用于包含 DISTINCTORDER 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_agghttp://pgxn.org/dist/first_last_agg/