My Postgres表架构有两个字段:
items
,其中包含(整数)项ID的数组。如果数组中的相同ID 两次,则将其视为主要项目。
primary_items
,我刚刚添加到架构中的另一个(整数)项ID数组,因此它在所有行中当前为空。
我需要做的是:对于每一行,检查items
中是否有重复的ID,如果是,请将每个重复的ID中的一个放入primary_items
字段。
有关如何使用查询处理此问题的任何想法?理想情况下,我不必编写帮助程序(Nodejs)来执行此操作,但如果需要,我可以。
示例:
当前:
documents_table
items primary_items
------------ -----------
{1, 2, 2, 4} {}
{1, 2, 3} {}
{3, 3} {}
{5, 4, 5, 4} {}
所需
documents_table
items primary_items
------------ -----------
{1, 2, 2, 4} {2}
{1, 2, 3} {}
{3, 3} {3}
{5, 4, 5, 4} {5,4}
答案 0 :(得分:3)
您可以通过以下简单查询找到重复的元素:
select array_agg(item)
from (
select item
from unnest('{5, 4, 5, 4}'::int[]) as item
group by item
having count(*) > 1
) s
array_agg
-----------
{4,5}
(1 row)
在函数中使用查询:
create or replace function find_primary_items(arr anyarray)
returns anyarray language sql immutable
as $$
select array_agg(item)
from (
select item
from unnest(arr) as item
group by item
having count(*) > 1
) s
$$;
现在更新非常容易:
update documents_table
set primary_items = coalesce(find_primary_items(items), '{}')
returning *;
items | primary_items
-----------+---------------
{1,2,2,4} | {2}
{1,2,3} | {}
{3,3} | {3}
{5,4,5,4} | {4,5}
(4 rows)
答案 1 :(得分:0)
您可以通过计算数组中加倍的元素来实现。取消嵌套数组,并使用row_number
窗口函数计算加倍的值:
https://www.postgresql.org/docs/current/static/functions-window.html
UPDATE documents_table -- E
SET primary_items = s.primaries
FROM (
SELECT
id,
array_agg(array_element) as primaries -- D.2
FROM (
SELECT
id,
array_element,
row_number() OVER (PARTITION BY id, array_element) as same_element_count -- C
FROM (
SELECT
items as id, -- A
unnest(items) as array_element -- B
FROM
documents_table
ORDER BY
id, array_element
) s
) s
WHERE same_element_count = 2 -- D.1
GROUP BY id) s
WHERE items = s.id;
A:需要一个ID。将该数组用作ID,但最好为此添加一个ID列
B:unnest
将数组扩展为每个元素一行。这是必需的,因为可以对行进行排序并将其用于进一步的窗口函数计算。
C:row_number
窗口函数:分区划分行。订购后,ID中的每个值都在同一分区中。如果ID中有两次或多次相同的值,则这些值在同一分区中。 row_number
计算一个分区中的元素。因此,双倍的值将获得行号'2'
D.1:过滤加倍的值
D.2:将每个ID的所有双精度值聚合到一个数组中。这将为您最后的primary_items
列
E:更新这些内容以计算表中的primary_items
数组。