【问题标题】:Find Min Or Max in custom aggregate function postgresql在自定义聚合函数 postgresql 中查找最小值或最大值
【发布时间】:2019-03-06 14:35:53
【问题描述】:

我是 Postgresql 的新手(我在 PL/pgSQL 中编程,与 sql 没有太大区别)。 我写了我的客户聚合函数,它必须在一个数字数组中找到最小值或最大值。 这是函数聚合代码

CREATE OR REPLACE FUNCTION searchMaxValue (numeric[]) RETURNS numeric AS $$
DECLARE 
i numeric;
maxVal numeric;
BEGIN
maxVal = $1[1];
IF ARRAY_LENGHT($1,1) > 0 THEN --Checking whether the array is empty or  not
   <<confrontoMassimo>>
   FOREACH i IN ARRAY $1 LOOP --Looping through the entire array, passed as parameter
       IF maxVal <= $1[i] THEN
           maxVal := $1[i];
       END IF;
   END LOOP confrontoMassimo;
   ELSE
   RAISE NOTICE 'Invalid parameter % passed to the aggregate function',$1;
   --Raising exception if the parameter passed as argument points to null.
   RAISE EXCEPTION 'Cannot find Max value. Parameter % is null', $1
   USING HINT = 'You cannot pass a null array! Check the passed parameter';

END IF;
RETURN maxVal;
END;
$$ LANGUAGE plpgsql;

 CREATE AGGREGATE searchMaxValueArray (numeric)
(
sfunc = array_append,
stype = numeric[],
finalfunc = searchMaxValue,
initCond = '{}'
);

问题是,它没有按预期工作。问题是什么?

【问题讨论】:

  • " 它没有按预期工作。" 不是一个很好的问题描述。是否抛出任何错误?它给出的结果是否与预期不同?如果是这样,请展示一些示例,说明预期的内容以及您从函数中获得的内容等。
  • ARRAY_LENGHT 应该是 ARRAY_LENGTH。这只是一个错字还是您的问题与此有关?
  • 你不能只使用unnestMAX/MIN 来完成这个吗?即:select MAX(id) FROM unnest(ARRAY[1,2,3]) AS t(id);
  • “我是 Postgres 的新手”和“我写了我的自定义聚合函数”并不是我们经常看到的两件事。编写自定义聚合函数是任何数据库中最复杂的事情之一。
  • 您应该在sfunc 而不是finalfunc 中执行最大值的计算,数组可能变得太大而无法处理。我认为您的功能没有根本问题,请描述故障。

标签: sql postgresql aggregate plpgsql


【解决方案1】:

如上所述,您的函数中有一个小错字; ARRAY_LENGHT 应该是 ARRAY_LENGTH

除此之外,我能看到的唯一问题是:

FOREACH i IN ARRAY $1 LOOP
    IF maxVal <= $1[i] THEN
        ...

FOREACH loop 中,目标变量i 不是数组索引,而是数组元素本身。换句话说,循环应该是:

FOREACH i IN ARRAY $1 LOOP
    IF maxVal <= i THEN
        maxVal := i;
    END IF;
END LOOP

通过这些更改,它似乎按预期工作:https://rextester.com/FTWB14034

【讨论】:

  • 尽管正如上面提到的@Laurenz,这是一种非常低效的方法。您不仅可能构建巨大的数组,而且每次附加新值时都会复制整个数组。但我想如果你想要一些高效的东西,你只需打电话给MAX() ;)
  • 这就是我想要的。我认为它像 Java 一样工作。谢谢,我按照你的建议解决了这个问题,没关系!
猜你喜欢
  • 1970-01-01
  • 2013-09-28
  • 2018-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多