我有一個表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
爲了反映意圖而編輯的問題。 –