两个阵列子集的总和

发布于 2025-01-30 17:08:47 字数 1743 浏览 3 评论 0 原文

我是Postgres阵列的新手。

我需要修改c数组的前4个元素

。公式为c [1:4] = a [1:4] + b [1:4] 该计算是通过group_name尺寸完成的,

是否有一种优雅的方法可以做到这一点,也许没有加入?

insert into the_table values
(1,'group 1', 'A', '{1,2,3,4,5}'), 
(2,'group 1', 'B', '{10,20,30,40,50}'),
(3,'group 2', 'A', '{-1,-2,-3,-4,-5}'), 
(4,'group 2', 'B', '{-10,-20,-30,-40,-50}'),
(5,'group 1', 'C', '{0,0,0,0,0}'), 
(6,'group 2', 'C', '{0,0,0,0,0}');

输入数据:

ID group_name var val
1 组1 A 1,2,3,4,5
2 组1 B 10,20,30,40,50
3 组1 C 0,0,0,0,0,0
4 组2 A组2 A -1,-2,-3,-4,-5
5 组2 B -10,-20,-30,-40,-50
6 组2 C 0,0,0,0,0,0,0

输出数据:

ID Group_Name VAL 组2 A
1 组1 A 1,2,3,4,5
2 组1 B 10,20,30,40,50
3 组1 C 11,22,33,44,0
4 组2 A -1,-2 ,-3,-4,-5
5 组2 B -10,-20,-30,-40,-50
6 组2 C -11,-22,-33,-44,0

I am new to postgres arrays.

I need to modify the first 4 elements of C arrays

The formulas is C[1:4] = A[1:4] + B[1:4]
This calculation is done over group_name dimension

Is there an elegant way of doing this, maybe without joins?

insert into the_table values
(1,'group 1', 'A', '{1,2,3,4,5}'), 
(2,'group 1', 'B', '{10,20,30,40,50}'),
(3,'group 2', 'A', '{-1,-2,-3,-4,-5}'), 
(4,'group 2', 'B', '{-10,-20,-30,-40,-50}'),
(5,'group 1', 'C', '{0,0,0,0,0}'), 
(6,'group 2', 'C', '{0,0,0,0,0}');

Input data:

id group_name var val
1 group 1 A 1,2,3,4,5
2 group 1 B 10,20,30,40,50
3 group 1 C 0,0,0,0,0
4 group 2 A -1,-2,-3,-4,-5
5 group 2 B -10,-20,-30,-40,-50
6 group 2 C 0,0,0,0,0

Output data:

id group_name var val
1 group 1 A 1,2,3,4,5
2 group 1 B 10,20,30,40,50
3 group 1 C 11,22,33,44,0
4 group 2 A -1,-2,-3,-4,-5
5 group 2 B -10,-20,-30,-40,-50
6 group 2 C -11,-22,-33,-44,0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷默言语 2025-02-06 17:08:47

您需要一个以给定的函数总和数组。

create or replace function sum_arrays(arr int[])
returns int[] language sql immutable as $
    select array[
        arr[1][1]+ arr[2][1],
        arr[1][2]+ arr[2][2],
        arr[1][3]+ arr[2][3],
        arr[1][4]+ arr[2][4],
        0]
$;

使用此功能,更新看起来非常优雅:

update the_table t
set val = sum_arrays
from (
    select group_name, sum_arrays(array_agg(val))
    from the_table
    where var in ('A', 'B')
    group by group_name
) s
where t.group_name = s.group_name
and t.var = 'C';

You need a function that sums arrays on a given basis.

create or replace function sum_arrays(arr int[])
returns int[] language sql immutable as $
    select array[
        arr[1][1]+ arr[2][1],
        arr[1][2]+ arr[2][2],
        arr[1][3]+ arr[2][3],
        arr[1][4]+ arr[2][4],
        0]
$;

With this function the update looks quite elegant:

update the_table t
set val = sum_arrays
from (
    select group_name, sum_arrays(array_agg(val))
    from the_table
    where var in ('A', 'B')
    group by group_name
) s
where t.group_name = s.group_name
and t.var = 'C';

Test it in db<>fiddle.

幸福不弃 2025-02-06 17:08:47

Postgres中的阵列没有分段操作。您不会遇到一些不符合阵列的加入,通过索引加入并将它们汇总回:

UPDATE the_table tab_c
SET val = (
  SELECT array_agg(a + b ORDER BY a_idx)
  FROM the_table tab_a,
  unnest(tab_a.val) WITH ORDINALITY AS val_a(a, a_idx),
  the_table tab_b,
  unnest(tab_b.val) WITH ORDINALITY AS val_b(b, b_idx)
  WHERE tab_a.group_name = tab_c.group_name
    AND tab_a.var = 'A'
    AND tab_b.group_name = tab_c.group_name
    AND tab_b.var = 'B'
    AND a_idx = b_idx
)
WHERE tab_c.var = 'C';
TABLE the_table;

在线演示

There are no piecewise operations on arrays in Postgres. You won't get around a few joins that unnest the arrays, join by index, and aggregate them back:

UPDATE the_table tab_c
SET val = (
  SELECT array_agg(a + b ORDER BY a_idx)
  FROM the_table tab_a,
  unnest(tab_a.val) WITH ORDINALITY AS val_a(a, a_idx),
  the_table tab_b,
  unnest(tab_b.val) WITH ORDINALITY AS val_b(b, b_idx)
  WHERE tab_a.group_name = tab_c.group_name
    AND tab_a.var = 'A'
    AND tab_b.group_name = tab_c.group_name
    AND tab_b.var = 'B'
    AND a_idx = b_idx
)
WHERE tab_c.var = 'C';
TABLE the_table;

(online demo)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文