use*_*987 19 arrays postgresql
我有一个包含4个数组列的表..结果如下:
ids signed_ids new_ids new_ids_signed
{1,2,3} | {2,1,3} | {4,5,6} | {6,5,4}
Run Code Online (Sandbox Code Playgroud)
无论如何要通过忽略元素的顺序来比较ids并使signed_ids它们相等?
Sel*_*maz 18
您可以使用运算符包含:
(array1 <@ array2和array1 @> array2)
Erw*_*ter 13
处理整数数组,您可以安装扩展名intarray.
使用(在Postgres 9.1或更高版本中)为每个数据库安装一次:
CREATE EXTENSION intarray;
Run Code Online (Sandbox Code Playgroud)
然后你可以:
SELECT uniq(sort(ids)) = uniq(sort(signed_ids));Run Code Online (Sandbox Code Playgroud)
要么:
SELECT ids @> signed_ids AND ids <@ signed_ids;Run Code Online (Sandbox Code Playgroud)
大胆强调来自intarray的功能和操作员.两个表达式都将忽略元素的顺序和重复性.更多有关这些功能和运营商在有帮助的手册在这里.
笔记:
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[]Run Code Online (Sandbox Code Playgroud)
有关:
泛型运算符不能将索引与intarray运算符类一起使用,反之亦然.
Cra*_*ger 11
最简单的方法是对它们进行排序并对它们进行排序.请参阅PostgreSQL中的排序数组.
给出样本数据:
CREATE TABLE aa(ids integer[], signed_ids integer[]);
INSERT INTO aa(ids, signed_ids) VALUES (ARRAY[1,2,3], ARRAY[2,1,3]);
Run Code Online (Sandbox Code Playgroud)
最好的办法是,如果数组条目总是整数,则使用intarray扩展,正如Erwin在他的回答中解释的那样.这是一个很多比任何纯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';
Run Code Online (Sandbox Code Playgroud)
并使用它排序和比较排序的数组:
SELECT array_sort(ids) = array_sort(signed_ids) FROM aa;
Run Code Online (Sandbox Code Playgroud)
有一个重要的警告:
SELECT array_sort( ARRAY[1,2,2,4,4] ) = array_sort( ARRAY[1,2,4] );
Run Code Online (Sandbox Code Playgroud)
将是假的.根据您的意图,这可能是您想要的,也可能不是.
或者,定义一个函数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;
Run Code Online (Sandbox Code Playgroud)
然后:
SELECT array_compare_as_set(ids, signed_ids) FROM aa;
Run Code Online (Sandbox Code Playgroud)
这与比较两个array_sorted值略有不同.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])将是假的.
这两种方法都会有相当糟糕的表现.考虑确保始终将数组存储在首位.
| 归档时间: |
|
| 查看次数: |
9733 次 |
| 最近记录: |