如何只选择两个数组之间的非匹配元素.
例:
base_array [12,3,5,7,8]
temp_array [3,7,8]
Run Code Online (Sandbox Code Playgroud)
所以在这里我要比较两个数组并从基础数组中删除匹配的元素.
现在base_array应该是这样的 [12,5]
Den*_*rdy 33
我将使用数组运算符来解决这个问题.
select array(select unnest(:arr1) except select unnest(:arr2));
Run Code Online (Sandbox Code Playgroud)
如果:arr1和:arr2不相交,则使用array_agg()会导致null.
a_h*_*ame 22
select array_agg(elements)
from (
select unnest(array[12,3,5,7,8])
except
select unnest(array[3,7,8])
) t (elements)
Run Code Online (Sandbox Code Playgroud)
Jos*_*rns 10
我构建了一组函数来专门处理这些类型的问题:https://github.com/JDBurnZ/anyarray
最重要的是这些函数适用于所有数据类型,而不是JUST整数,intarray仅限于此.
加载从GitHub加载这些SQL文件中定义的函数后,您需要做的就是:
SELECT
ANYARRAY_DIFF(
ARRAY[12, 3, 5, 7, 8],
ARRAY[3, 7, 8]
)
Run Code Online (Sandbox Code Playgroud)
返回类似于: ARRAY[12, 5]
如果还需要返回已排序的值:
SELECT
ANYARRAY_SORT(
ANYARRAY_DIFF(
ARRAY[12, 3, 5, 7, 8],
ARRAY[3, 7, 8]
)
)
Run Code Online (Sandbox Code Playgroud)
完全返回: ARRAY[5, 12]
让我们尝试不必要的()/除外:
EXPLAIN ANALYZE SELECT array(select unnest(ARRAY[1,2,3,n]) EXCEPT SELECT unnest(ARRAY[2,3,4,n])) FROM generate_series( 1,10000 ) n;
Function Scan on generate_series n (cost=0.00..62.50 rows=1000 width=4) (actual time=1.373..140.969 rows=10000 loops=1)
SubPlan 1
-> HashSetOp Except (cost=0.00..0.05 rows=1 width=0) (actual time=0.011..0.011 rows=1 loops=10000)
-> Append (cost=0.00..0.04 rows=2 width=0) (actual time=0.002..0.008 rows=8 loops=10000)
-> Subquery Scan "*SELECT* 1" (cost=0.00..0.02 rows=1 width=0) (actual time=0.002..0.003 rows=4 loops=10000)
-> Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.001..0.002 rows=4 loops=10000)
-> Subquery Scan "*SELECT* 2" (cost=0.00..0.02 rows=1 width=0) (actual time=0.001..0.003 rows=4 loops=10000)
-> Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.001..0.002 rows=4 loops=10000)
Total runtime: 142.531 ms
Run Code Online (Sandbox Code Playgroud)
和intarray特别运营商:
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
Run Code Online (Sandbox Code Playgroud)
基线:
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
Run Code Online (Sandbox Code Playgroud)
每个阵列交叉时间:
intarray - : 0.4 µs
unnest() / intersect : 13.4 µs
Run Code Online (Sandbox Code Playgroud)
当然,intarray的方式要快得多,但我发现postgres可以在13.4μs中删除一个依赖子查询(包含一个哈希和其他东西),真是太棒了......
| 归档时间: |
|
| 查看次数: |
14959 次 |
| 最近记录: |