如何将一个数组的匹配元素排除在另一个数组之外?
Postgres代码:
a1 := '{1, 2, 5, 15}'::int[];
a2 := '{1, 2, 3, 6, 7, 9, 15}'::int[];
a3 := a2 ??magic_operator?? a1;
在a3
中我完全期待' {3,6,7,9}'
最终结果
我和lad2025解决方案运行良好。
需要array_position()
的解决方案 PostgreSQL 9.5 以及之后,更快地执行x3。
答案 0 :(得分:2)
在数组之间看起来像XOR
:
WITH set1 AS
(
SELECT * FROM unnest('{1, 2, 5, 15}'::int[])
), set2 AS
(
SELECT * FROM unnest('{1, 2, 3, 6, 7, 9, 15}'::int[])
), xor AS
(
(SELECT * FROM set1
UNION
SELECT * FROM set2)
EXCEPT
(SELECT * FROM set1
INTERSECT
SELECT * FROM set2)
)
SELECT array_agg(unnest ORDER BY unnest)
FROM xor
输出:
"{3,5,6,7,9}"
工作原理:
或者你可以使用减号(除)操作的总和:
(A+B) - (A^B)
<=>
(A-B) + (B-A)
利用FULL JOIN
:
WITH set1 AS
(
SELECT *
FROM unnest('{1, 2, 5, 15}'::int[])
), set2 AS
(
SELECT *
FROM unnest('{1, 2, 3, 6, 7, 9, 15}'::int[])
)
SELECT array_agg(COALESCE(s1.unnest, s2.unnest)
ORDER BY COALESCE(s1.unnest, s2.unnest))
FROM set1 s1
FULL JOIN set2 s2
ON s1.unnest = s2.unnest
WHERE s1.unnest IS NULL
OR s2.unnest IS NULL;
修改强>
如果您只希望第二个数组中的元素不是第一个使用简单的EXCEPT
:
SELECT array_agg(unnest ORDER BY unnest)
FROM (SELECT * FROM unnest('{1, 2, 3, 6, 7, 9, 15}'::int[])
EXCEPT
SELECT * FROM unnest('{1, 2, 5, 15}'::int[])) AS sub
输出:
"{3,6,7,9}"
答案 1 :(得分:1)
我发现了一些类似的案例并进行了修改。
那个SQL解决了我的问题。
with elements (element) as (
select unnest(ARRAY[1, 2, 3, 6, 7, 9, 15])
)
select array_agg(element)
from elements
where array_position(ARRAY[1, 2, 5, 15],element) is null
需要PostgreSQL 9.5及更高版本。
答案 2 :(得分:1)
附加模块intarray
为整数数组提供简单快速的subtraction operator -
,正是您正在寻找的 magic_operator :
test=# SELECT '{1, 2, 3, 6, 7, 9, 15}'::int[] - '{1, 2, 5, 15}'::int[] AS result;
?column?
-----------
{3,6,7,9}
您需要为每个数据库安装一次模块:
CREATE EXTENSION intarray;
它还为索引提供了特殊的运算符类:
...无null的整数数组。