EXPLAIN ANALYZE SELECT ARRAY[1,2,3,n] - ARRAY[2,3,4,n] FROM generate_series( 1,10000 ) n;
Function Scan on generate_series n (cost=0.00..15.00 rows=1000 width=4) (actual time=1.338..11.381 rows=10000 loops=1)
Total runtime: 12.306 ms
基线:
EXPLAIN ANALYZE SELECT ARRAY[1,2,3,n], ARRAY[2,3,4,n] FROM generate_series( 1,10000 ) n;
Function Scan on generate_series n (cost=0.00..12.50 rows=1000 width=4) (actual time=1.357..7.139 rows=10000 loops=1)
Total runtime: 8.071 ms
CREATE FUNCTION array_subtract(a1 int[], a2 int[]) RETURNS int[] AS $$
DECLARE
ret int[];
BEGIN
IF a1 is null OR a2 is null THEN
return a1;
END IF;
SELECT array_agg(e) INTO ret
FROM (
SELECT unnest(a1)
EXCEPT
SELECT unnest(a2)
) AS dt(e);
RETURN ret;
END;
$$ language plpgsql;
CREATE OR REPLACE FUNCTION array_difference_ordered(array1 anyarray, array2 anyarray)
RETURNS anyarray
LANGUAGE sql
IMMUTABLE AS
$$
SELECT ARRAY_AGG(array1_ordered_row.element ORDER BY array1_ordered_row.ordering)
FROM UNNEST(array1) WITH ORDINALITY AS array1_ordered_row(element, ordering)
WHERE NOT EXISTS
(
SELECT 1
FROM UNNEST(array2) AS array2_row(element)
WHERE array1_ordered_row.element = array2_row.element
)
$$;
8条答案
按热度按时间r7xajy2e1#
我会用数组运算符来处理这个问题。
如果:arr1和:arr2不相交,则使用array_agg()会导致空值。
2w3rbyxf2#
4xrmg8kj3#
我构造了一组函数来专门处理这类问题:https://github.com/JDBurnZ/anyarray
最棒的是这些函数可以在所有数据类型上工作,而不仅仅是整数,因为
intarray
是有限的。从GitHub加载完这些SQL文件中定义的函数后,你需要做的就是:
返回类似于以下内容的内容:
ARRAY[12, 5]
如果还需要返回排序后的值:
准确返回:
ARRAY[5, 12]
pvcm50d14#
让我们试试unnest()/ except:
而阵列内特殊运算符:
基线:
每个阵列交叉点的时间:
当然,intarray的方式要快得多,但我发现postgres可以在13.4 µs内快速处理一个依赖子查询(包含散列和其他内容),这令人惊讶。
xsuvu9jc5#
contrib/intarray模块提供了这种功能--不管怎样,是针对整数数组的,对于其他数据类型,您可能需要编写自己的函数(或者修改intarray提供的函数)。
2ic8powd6#
Denis答案的一个扩展,它返回差值,而不管先输入哪个数组。这不是最简洁的查询,也许有人有更整洁的方法。
退货:
jm2pwxwz7#
我将使用与@a_horse_with_no_name描述的相同的except逻辑创建一个函数:
然后可以使用此函数相应地更改base_array变量:
使用@Denis的快速解决方案,并且只使用SQL,我们可以将泛型函数表示为
r55awzrz8#
这是我的建议-它与其他答案的不同之处在于以下几点: