简体   繁体   English

自定义聚合函数

[英]Custom aggregate function

I am trying to understand aggregate functions and I need help. 我想了解集合函数,我需要帮助。

So for instance the following sample: 例如,以下示例:

CREATE OR REPLACE FUNCTION array_median(timestamp[])
  RETURNS timestamp AS
$$
    SELECT CASE WHEN array_upper($1,1) = 0 THEN null ELSE asorted[ceiling(array_upper(asorted,1)/2.0)] END
    FROM (SELECT ARRAY(SELECT ($1)[n] FROM
generate_series(1, array_upper($1, 1)) AS n
    WHERE ($1)[n] IS NOT NULL
            ORDER BY ($1)[n]
) As asorted) As foo ;
$$
  LANGUAGE 'sql' IMMUTABLE;


CREATE AGGREGATE median(timestamp) (
  SFUNC=array_append,
  STYPE=timestamp[],
  FINALFUNC=array_median
)

I am not understanding the structure/logic that needs to go into the select statement in the aggregate function itself. 我不理解需要进入聚合函数本身的select语句的结构/逻辑。 Can someone explain what the flow/logic is? 有人可以解释一下流/逻辑是什么吗?

I am writing an aggregate, a strange one, that the return is always the first string it ever sees. 我正在编写一个聚合,一个奇怪的聚合,返回始终是它看到的第一个字符串。

You're showing a median calculation, but want the first text value you see? 您正在显示中位数计算,但想要看到第一个文本值?

Below is how to do that. 以下是如何做到这一点。 Assuming you want the first non-null value, that is. 假设您想要第一个非空值,即。 If not, you'll need to keep track of if you've got a value already or not. 如果没有,你需要跟踪你是否已经拥有一个价值。

The accumulator function is written as plpgsql and sql - the plpgsql one lets you use variable names and debug it too. 累加器函数写为plpgsql和sql - plpgsql允许你使用变量名并调试它。 It simply uses COALESCE against the previous accumulated value and the new value and returns the first non-null. 它只是对前一个累计值和新值使用COALESCE并返回第一个非null值。 So - as soon as you have a non-null in the accumulator everything else gets ignored. 所以 - 只要你在累加器中有一个非null,其他一切都会被忽略。

You may also want to consider the "first_value" window function for this sort of thing if you're on a modern (8.4+) version of PostgreSQL. 如果您使用的是PostgreSQL的现代(8.4+)版本,您可能还需要考虑这种事情的“first_value”窗口函数。

http://www.postgresql.org/docs/9.1/static/functions-window.html http://www.postgresql.org/docs/9.1/static/functions-window.html

HTH HTH

BEGIN;

CREATE FUNCTION remember_first(acc text, newval text) RETURNS text AS $$
BEGIN
    RAISE NOTICE '% vs % = %', acc, newval, COALESCE(acc, newval);
    RETURN COALESCE(acc, newval);
END;
$$ LANGUAGE plpgsql IMMUTABLE;

CREATE FUNCTION remember_first_sql(text,text) RETURNS text AS $$
    SELECT COALESCE($1, $2);
$$ LANGUAGE SQL IMMUTABLE;

-- No "initcond" means we start out with null
--      
CREATE AGGREGATE first(text) (
    sfunc = remember_first,
    stype = text
);

CREATE TEMP TABLE tt (t text);
INSERT INTO tt VALUES ('abc'),('def'),('ghi');

SELECT first(t) FROM tt;

ROLLBACK;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM