【问题标题】:Custom aggregate function自定义聚合函数
【发布时间】:2011-12-02 00:44:09
【问题描述】:

我正在尝试理解聚合函数,我需要帮助。

例如以下示例:

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
)

我不了解需要进入聚合函数本身的 select 语句的结构/逻辑。有人能解释一下流程/逻辑是什么吗?

我正在写一个聚合,一个奇怪的聚合,返回总是它见过的第一个字符串。

【问题讨论】:

    标签: sql postgresql aggregate-functions


    【解决方案1】:

    您显示的是中位数计算,但想要看到的第一个文本值?

    下面是如何做到这一点。假设您想要第一个非空值,即。如果没有,您需要跟踪您是否已经获得了值。

    累加器函数被编写为 plpgsql 和 sql - plpgsql 允许您使用变量名并对其进行调试。它只是对先前的累积值和新值使用 COALESCE 并返回第一个非空值。所以 - 一旦你在累加器中有一个非空值,其他所有东西都会被忽略。

    如果您使用的是现代 (8.4+) 版本的 PostgreSQL,您可能还需要考虑“first_value”窗口函数。

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

    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;
    

    【讨论】:

    • 正是我需要的,谢谢。我认为聚合函数不必在数组上工作?
    • 涉及到两种类型 - 聚合的内容和累积的内容。 PostgreSQL 为你创建了一个变量 (STYPE=),如果你正在做类似中值的事情,它可能需要是一个数组。对于这种情况,或者类似“join_text”的东西,你可以保持简单。
    猜你喜欢
    • 2019-11-05
    • 1970-01-01
    • 2016-01-30
    • 2012-01-19
    • 2016-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-04
    相关资源
    最近更新 更多