首页 > 解决方案 > 函数循环遍历数组元素的语法?

问题描述

这是我第一次尝试在 Postgres 中构建函数,也是第一次使用数组。关于 Stackoverflow 的第一个问题!

有一个 2 级数字数组{{a1,b1},{a2,b2}...{ai,bi}}。试图计算三件事:

  1. 想循环并乘以每个子数组 ie(a1 * b1)然后在数组内累加,直到达到某个数字 (x) ie (a1 * b1) + (a2 * b2)... + ...(ai * bi) >= xai * bi推动上述累积的第一个子数组也是如此x。我想返回这个累积的数字。

  2. 累积 B. 即(b1 + b2 +...+ bi)

  3. 艾。

在循环之外,我想做一些涉及这三个数字的计算。

无法包含 DO 来本地化变量,但如果可能的话,那会很棒。

查看大约 1M 行。每行可以包含主数组中的数百个子数组元素,但我不太可能需要每行超过 8 个子数组相乘和求和。

Postgres 9.6。

我已经查看了数组中的foreach和 slice,但不确定在这种情况下是否可以使用。不确定 unnest 是否有任何好处。目前没有索引。

CREATE OR REPLACE FUNCTION accum (numeric[i],numeric[i]) RETURNS numeric AS 
$$

DECLARE
x integer := 100;
y numeric;
z numeric;

BEGIN
  LOOP

-- Accumulate subarray products
  y := SELECT(ANYARRAY)[i:i][1:1]*SELECT(ANYARRAY)[i:i][2:2] + y;

-- Accumulate 2nd element of subarrays
  z := SELECT(ANYARRAY)[i:i][2:2] + z;

EXIT WHEN y > x; 

END LOOP;

RETURN y,
       z,
       -- Return first element of subarray that makes y > x
       SELECT(ANYARRAY)[i:i][1:1];

"Calculation involving output"

END
$$
LANGUAGE plpgsql
;

我不确定如何从循环中返回多个输出。旨在从此函数中获得单个数字输出。任何有关我将如何处理的语法或方法的帮助将不胜感激!甚至可以在没有功能的情况下完成所有这些工作吗?谢谢阅读。

标签: postgresql

解决方案


Postgres 中的多维数组不是直接实现的,因为子数组不是“元素”。我建议您使用一种类型(a,b)然后传递该类型的数组。以这种方式引用元素更容易。

创建类型

create type abtype AS( a numeric, b numeric);

功能

CREATE OR REPLACE FUNCTION accum (abtyparray abtype[]) RETURNS numeric AS 
$$

DECLARE
x integer := 100;
ab abtype;
y numeric := 0;
z numeric := 0;

BEGIN

   FOREACH ab IN ARRAY abtyparray 
   LOOP
     y := y + ab.a * ab.b; --(a1 * b1) + (a2 * b2)... + ...(ai * bi) 
     z := z + ab.b;  --Cumulative b
     EXIT WHEN y > x; 
   END LOOP;
     RAISE NOTICE 'y = %, z= %,ai = % ', y,z,ab.a;
                                            --^ai
    RETURN y;

END
$$
LANGUAGE plpgsql;

执行

knayak=# DO $$
knayak$# BEGIN
knayak$# PERFORM  accum (ARRAY[(3,4),(10,9),(17,19)] ::abtype[] ) ;
knayak$# END $$;
NOTICE:  y = 102, z= 13,ai = 10
DO

演示


推荐阅读