检查Postgres数组是否按顺序包含子数组

时间:2017-10-08 23:03:21

标签: sql arrays postgresql

我需要编写一个SQL(或SQL函数)来检查Postgres项是否包含项目的一部分。我只是将这个项目称为“项目”。所以基本上'Item'看起来像这样:

enter image description here

e1的大小始终与e2相同。

现在有两个数组,我只是称它们为a1和a2,看起来像这样。

'{b,c,d}','{2,3,4}'。

e2(a2)中的值必须与e1(a1)中的索引完全匹配,因此在本例中,表中的第1项和第4项都匹配,但不匹配第2项或第3项。因此,如果2个数组是“{c,d}”,“{3,4}”,那么第1个,第3个和第4个项目将匹配。

我不知道如何做到这一点,我是否需要使用像generate_series()之类的东西来生成所有可能的项目切片,然后检查?我现在有点困惑。

1 个答案:

答案 0 :(得分:0)

该函数返回子数组arr的数组sub中的索引,如果arr不包含sub,则返回0:

create or replace function index_of_subarray(arr anyarray, sub anyarray)
returns integer language plpgsql immutable as $$
begin
    for i in 1 .. cardinality(arr)- cardinality(sub)+ 1 loop
        if arr[i:i+ cardinality(sub)- 1] = sub then
            return i;
        end if;
    end loop;
    return 0;
end $$;

使用:

with my_table(e1, e2) as (
values
    ('{a,b,c,d}'::text[], '{1,2,3,4}'::int[]),
    ('{b,c,d,a}', '{1,2,3,4}'),
    ('{c,d}', '{3,4}'),
    ('{b,c,d}', '{2,3,4}')
)

select e1, e2
from my_table
where index_of_subarray(e1, '{b,c,d}') > 0 
and index_of_subarray(e1, '{b,c,d}') = index_of_subarray(e2, '{2,3,4}')

    e1     |    e2     
-----------+-----------
 {a,b,c,d} | {1,2,3,4}
 {b,c,d}   | {2,3,4}
(2 rows)