PostgreSQL二维数组交集

时间:2012-08-09 10:52:43

标签: sql arrays postgresql intersection

是否可以使用postgres工具与二维数组相交?

例如我有:

id               arr
1    {{1,2}, {3,4}, {4,5}, {4,7}}
2    {{4,2}, {7,4}, {8,5}, {9,7}}

...

我希望获得所有在其数组中都有{4,5}的记录,并在此处记录id=1
如果我这样做:

select * from table where arr && '{4,5}'

我将获得这两个示例记录。它找到4和5的所有记录都在数组中的任何位置 - 好像它正在查找完全提取的数组,如{1,2,3,4,4,5,4,7}

1 个答案:

答案 0 :(得分:2)

我想过使用扩展程序intarray中的函数,但是:

  

这些操作中的许多只对一维数组有效。   虽然它们会接受更多维度的输入数组,但数据却是   在存储顺序中处理就好像它是一个线性数组

我的其他想法:

又快又脏

WITH x(id, arr) AS (VALUES
    (1, '{{1,2}, {3,4}, {4,5}, {4,7}}'::int[])
   ,(2, '{{4,2}, {7,4}, {8,5}, {9,7}}')
   )
SELECT * 
FROM   x
WHERE  arr::text LIKE '%{4,5}%';

简单的技巧是将数组转换为文本表示形式,并使用LIKE进行检查。

使用数组函数

WITH x(id, arr) AS (
    VALUES
     (1, '{{1,2}, {3,4}, {4,5}, {4,7}}'::int[])
    ,(2, '{{4,2}, {7,4}, {8,5}, {9,7}}')
    )
    ,y AS (
    SELECT id, arr, generate_subscripts(arr, 1) AS i
    FROM   x
)
SELECT id, arr
FROM   y
WHERE  arr[i:i] = '{{4,5}}'::int[];

或者,以不同的符号表示,以你的例子为基础:

SELECT id, arr
FROM  (
    SELECT id, arr, generate_subscripts(arr, 1) AS i
    FROM   tbl
    ) x
WHERE  arr[i:i] = '{{4,5}}'::int[];

这将生成第一个维度的数组下标。在这个set-returns函数的帮助下,我们检查每个数组切片。请注意表达式右侧的双括号,以创建匹配的二维数组。

如果{4,5}多次出现arr,请添加GROUP BYDISTINCT子句以避免重复行。