在 JSONB 数组中强制唯一性

Force uniqueness in JSONB array

假设我有一个 table students,列类型为 jsonb,我在其中存储了一个列表,其中包含学生的其他电子邮件。学生行看起来像这样

student_id name emails
1 John Doe [j.doe@email.com]

我正在使用以下查询来更新 emails 列:

UPDATE students SET emails = emails || '["j.doe@email.com"]'::jsonb
                     WHERE student_id=1
                     AND NOT emails @> '["j.doe@email.com"]'::jsonb;

填充 emails 列后,如果我使用参数 ["j.doe@email.com", "john@email.com"] 重复使用上面的查询,则 emails 列将更新为重复值:

student_id name emails
1 Student 1 [j.doe@email.com, j.doe@email.com, john@email.com]

有没有办法确保在 emails 列中我将始终拥有一个仅包含唯一值的 jsonb 列表?

使用这个方便的函数从 jsonb 数组中删除重复项:

create or replace function jsonb_unique_array(jsonb)
returns jsonb language sql immutable as $$
    select jsonb_agg(distinct value)
    from jsonb_array_elements() 
$$;

您的更新语句可能如下所示:

update students 
set emails = jsonb_unique_array(emails || '["j.doe@email.com", "john@email.com"]'::jsonb)
where student_id=1
and not emails @> '["j.doe@email.com", "john@email.com"]'::jsonb

db<>fiddle.

中测试