我有一个包含4个数组列的表..结果如下:
ids signed_ids new_ids new_ids_signed
{1,2,3} | {2,1,3} | {4,5,6} | {6,5,4}
无论如何要通过忽略元素的顺序来比较ids
和signed_ids
以使它们相等?
答案 0 :(得分:16)
您可以使用运营商包含的内容:
(array1< @ array2 and array1 @> array2)
答案 1 :(得分:12)
处理整数数组,您可以安装扩展程序intarray。
每个数据库安装一次(在Postgres 9.1或更高版本中):
CREATE EXTENSION intarray;
然后你可以:
SELECT uniq(sort(ids)) = uniq(sort(signed_ids));
或者:
SELECT ids @> signed_ids AND ids <@ signed_ids;
大胆强调来自intarray的功能和操作员。 两个表达式都将忽略元素的顺序和重复性。有用的手册here中有关这些功能和操作员的更多信息。
注意:
intarray
运算符仅适用于integer
,而不是bigint
或smallint
或任何其他数据类型的数组。@>
的情况下使用包含运算符<@
和intarray
,因为标准Postgres分发中的数组类型有通用变体。 intarray
仅为int[]
安装专用运算符,这些运算符通常更快。与通用运算符不同,intarray
不接受数组中的NULL值,这可能令人困惑:如果在任何涉及的数组中有NULL,则现在会收到错误消息。
如果您需要使用NULL值,则可以通过使用OPERATOR
构造对运算符进行模式限定来默认为标准的泛型运算符:
SELECT ARRAY[1,4,null,3]::int[] OPERATOR(pg_catalog.@>) ARRAY[3,1]::int[]
相关:
泛型运算符不能使用intarray
运算符类的索引,反之亦然。
答案 2 :(得分:10)
最简单的方法是对它们进行排序并对它们进行排序。请参阅sorting arrays in PostgreSQL。
给出样本数据:
CREATE TABLE aa(ids integer[], signed_ids integer[]);
INSERT INTO aa(ids, signed_ids) VALUES (ARRAY[1,2,3], ARRAY[2,1,3]);
最好的办法是,如果数组条目总是整数,则使用intarray扩展名为Erwin explains in his answer。它比任何纯SQL公式都快很多。
否则,对于适用于任何数据类型的通用版本,请定义array_sort(anyarray)
:
CREATE OR REPLACE FUNCTION array_sort(anyarray) RETURNS anyarray AS $$
SELECT array_agg(x order by x) FROM unnest($1) x;
$$ LANGUAGE 'SQL';
并使用它对排序的数组进行排序和比较:
SELECT array_sort(ids) = array_sort(signed_ids) FROM aa;
有一个重要的警告:
SELECT array_sort( ARRAY[1,2,2,4,4] ) = array_sort( ARRAY[1,2,4] );
将是假的。根据您的意图,这可能是您想要的,也可能不是。
或者,定义一个函数array_compare_as_set
:
CREATE OR REPLACE FUNCTION array_compare_as_set(anyarray,anyarray) RETURNS boolean AS $$
SELECT CASE
WHEN array_dims($1) <> array_dims($2) THEN
'f'
WHEN array_length($1,1) <> array_length($2,1) THEN
'f'
ELSE
NOT EXISTS (
SELECT 1
FROM unnest($1) a
FULL JOIN unnest($2) b ON (a=b)
WHERE a IS NULL or b IS NULL
)
END
$$ LANGUAGE 'SQL' IMMUTABLE;
然后:
SELECT array_compare_as_set(ids, signed_ids) FROM aa;
这与比较两个array_sort
ed值略有不同。 array_compare_as_set
将消除重复项,使array_compare_as_set(ARRAY[1,2,3,3],ARRAY[1,2,3])
为真,而array_sort(ARRAY[1,2,3,3]) = array_sort(ARRAY[1,2,3])
则为假。
这两种方法都会有相当糟糕的表现。请考虑确保始终将数组存储在第一位。
答案 3 :(得分:0)
如果您的数组没有重复且尺寸相同:
@>
array_length
的长度必须与您想要的两边的大小都匹配答案 4 :(得分:-1)
从以下选项中选择(string_agg(a,','by a order)= string_agg(b,','by b order)) (选择unnest(array [1,2,3,2]):: text为a,unnest(array [2,2,3,1]):: text如b)A