这是我第一次尝试在Postgres中构建函数,也是第一次使用数组。还有关于Stackoverflow的第一个问题!
有一个{{a1,b1},{a2,b2}...{ai,bi}}
的2级数字数组。
试图计算三件事:
想要遍历并乘以每个子数组,即(a1 * b1)
,然后在数组中累积,直到达到某个数字(x),即(a1 * b1) + (a2 * b2)... + ...(ai * bi) >= x
。因此ai * bi
是第一个将累积量推到x
以上的子数组。我想返回这个累积的数字。
累积b。即(b1 + b2 +...+ bi)
。
ai。
在循环之外,我想做一些涉及这三个数字的计算。
无法包含DO来对变量进行本地化,但是如果可能的话,那会很棒。
看大约一百万行。每行可以在主数组中包含数百个子数组元素,但我不太可能需要将每行的8个子数组相乘并相加。
Postgres 9.6。
我查看了 foreach 和数组中的切片,但不确定在这种情况下是否适合使用。 不知道嵌套是否有任何好处。 当前没有索引。
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
;
我不确定如何从循环返回多个输出。 旨在从此功能获得单个数字输出。 对于语法或方法方面的任何帮助,将不胜感激!没有功能甚至可以做所有这些事情吗?感谢您的阅读。
答案 0 :(得分:0)
Postgres中的多维数组不是直接实现的,因为子数组不是“元素”。建议您使用(a,b)
的 type 然后传递该类型的数组。这样更容易引用元素。
创建类型
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