我有一个表4个阵列列的顺序..结果是这样的:比较是否相等阵列,忽略元件
ids signed_ids new_ids new_ids_signed
{1,2,3} | {2,1,3} | {4,5,6} | {6,5,4}
反正比较ids
和signed_ids
使得它们出来相等,通过忽略元素的顺序?
我有一个表4个阵列列的顺序..结果是这样的:比较是否相等阵列,忽略元件
ids signed_ids new_ids new_ids_signed
{1,2,3} | {2,1,3} | {4,5,6} | {6,5,4}
反正比较ids
和signed_ids
使得它们出来相等,通过忽略元素的顺序?
最简单的事情就是对它们进行排序并对它们进行排序。见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。这是一个lot比任何纯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])
将为假。
这两种方法都会有很差的表现。考虑确保您始终将您的数组存储在首位。
为你的餐桌添加一个别名,精彩!谢谢:) – user766987
@ user766987更新了更好的定义 –
@ user766987 ...并用不同的方法再次更新,只是为了好玩。 –
处理数组整数您可以安装扩展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
。 intarray
只为int[]
安装专门的操作员,通常速度更快。与泛型操作符不同,intarray
不接受数组中的NULL值,这可能会造成混淆:现在,如果在任何涉及的数组中都有NULL,则会收到错误消息。
如果需要使用NULL值的工作,你可以默认为标准,一般运营商通过架构进行资格与OPERATOR
构建运营商:
SELECT ARRAY[1,4,null,3]::int[] OPERATOR([email protected]>) ARRAY[3,1]::int[]
通用运营商不能使用索引与一个intarray
操作符类,反之亦然。
您可以使用包含在由操作者:
(ARRAY1 < @数组2和ARRAY1 @>数组2)
这些阵列是不相等的。我猜对了,你真正的问题是“如何比较两个PostgreSQL数组,就好像它们是集合一样,即不考虑顺序?” –
是的,这正是我要求的:) – user766987
为了反映意图而编辑的问题。 –