Sql postgres中的自定义聚合函数返回空值

Sql postgres中的自定义聚合函数返回空值,sql,postgresql,aggregate-functions,Sql,Postgresql,Aggregate Functions,为了创建更复杂的自定义聚合函数,我首先遵循以下步骤 以下是我使用的数据: create table entries( id serial primary key, amount float8 not null ); select setseed(0); insert into entries(amount) select (2000 * random()) - 1000 from generate_series(1, 1000000); 我有一张桌子: id |

为了创建更复杂的自定义聚合函数,我首先遵循以下步骤

以下是我使用的数据:

create table entries(
  id serial primary key,
  amount float8 not null
);

select setseed(0);

insert into entries(amount)
select (2000 * random()) - 1000
from generate_series(1, 1000000);
我有一张桌子:

 id      |        amount         |   running_total
---------+-----------------------+--------------------
       1 |     -462.016298435628 |  -462.016298435628
       2 |      162.440904416144 |  -299.575394019485
       3 |     -820.292402990162 |  -1119.86779700965
       4 |     -866.230697371066 |  -1986.09849438071
       5 |      -495.30001822859 |   -2481.3985126093
       6 |      772.393747232854 |  -1709.00476537645
       7 |     -323.866365477443 |  -2032.87113085389
       8 |     -856.917716562748 |  -2889.78884741664
       9 |      285.323366522789 |  -2604.46548089385
      10 |     -867.916810326278 |  -3472.38229122013
-- snip --
我想要
running\u total
列的最大值
(我知道我不需要新的聚合函数也能做到,但这是为了演示)

所以我做了这个聚合函数

create or replace function grt_sfunc(agg_state point, el float8)
returns point
immutable
language plpgsql
as $$
declare
  greatest_sum float8;
  current_sum float8;
begin
    current_sum := agg_state[0] + el;
    greatest_sum := 40;
    /*if agg_state[1] < current_sum then
        greatest_sum := current_sum;
    else
        greatest_sum := agg_state[1];
    end if;*/
    return point(current_sum, greatest_sum);
    /*return point(3.14159, 0);*/
end;
$$;

create or replace function grt_finalfunc(agg_state point)
returns float8
immutable
strict
language plpgsql
as $$
begin
  return agg_state[0];
end;
$$;

create or replace aggregate greatest_running_total (float8)
(
    sfunc = grt_sfunc,
    stype = point,
    finalfunc = grt_finalfunc
);
我试图改变数据的类型,分别检查两个第一个聚合函数,它们工作得很好。有人能帮我找到解决办法吗?:)


多谢各位

您需要为聚合设置一个非NULL的
initcond
。大概是
(0,0)
,或者可能是负数,每个都是非常大的数?或者手动检查agg_状态是否为空


此外,您的grt_finalfunc似乎应该返回下标[1],而不是[0]。

您需要为聚合设置一个非NULL的initcond。大概是
(0,0)
,或者可能是负数,每个都是非常大的数?或者手动检查agg_状态是否为空


此外,您的grt_finalfunc似乎应该返回下标[1],而不是[0]。因此,解决方案是添加初始条件。实际上,如果没有初始条件,第一个值被认为是NULL:D(谢谢@jjanes和@Impaler)

所以我修正了ma聚合函数:

create or replace aggregate greatest_running_total (float8)
(
    sfunc = grt_sfunc,
    stype = point,
    finalfunc = grt_finalfunc,
    initcond = '(0,0)'
);
实际上,SQL从1而不是从0索引其表。。。这是我的第二个错误


非常感谢

因此,解决方案是添加一个初始条件。实际上,如果没有初始条件,第一个值被认为是NULL:D(谢谢@jjanes和@Impaler)

所以我修正了ma聚合函数:

create or replace aggregate greatest_running_total (float8)
(
    sfunc = grt_sfunc,
    stype = point,
    finalfunc = grt_finalfunc,
    initcond = '(0,0)'
);
实际上,SQL从1而不是从0索引其表。。。这是我的第二个错误


非常感谢

任意数字+null=null。只添加非空值。我只添加非空值:/但是我想我发现了问题,没有初始条件!!所以第一个值是null!!谢谢;)任意数字+null=null。只添加非空值。我只添加非空值:/但是我想我发现了问题,没有初始条件!!所以第一个值是null!!谢谢;)