是否可以使用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}
。
答案 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 BY
或DISTINCT
子句以避免重复行。