排除匹配的数组元素

时间:2016-01-15 21:14:45

标签: sql arrays postgresql

如何将一个数组的匹配元素排除在另一个数组之外?

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。

3 个答案:

答案 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}"

工作原理:

  1. Unnest two arrays
  2. 计算SUM
  3. 计算INTERSECT
  4. 来自SUM - INTERSECT
  5. 合并到数组
  6. 或者你可以使用减号(除)操作的总和:

    (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;

它还为索引提供了特殊的运算符类:

请注意only works for:

  

...无null的整数数组。