Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Postgres-查找数组的最小值_Sql_Arrays_Postgresql_Min_Unnest - Fatal编程技术网

Sql Postgres-查找数组的最小值

Sql Postgres-查找数组的最小值,sql,arrays,postgresql,min,unnest,Sql,Arrays,Postgresql,Min,Unnest,假设我有一张这样的桌子: link_ids | length ------------+----------- {1,4} | {1,2} {2,5} | {0,1} 如何找到每个链接ID的最小长度 因此,最终输出类似于: link_ids | length ------------+----------- {1,4} | 1 {2,5} | 0 我假设link_id可以有两个,既然没有id列,我们就临时凑合一下 WITH r

假设我有一张这样的桌子:

  link_ids  |  length
------------+-----------
 {1,4}      | {1,2}
 {2,5}      | {0,1}
如何找到每个链接ID的最小长度

因此,最终输出类似于:

  link_ids  |  length
------------+-----------
 {1,4}      | 1
 {2,5}      | 0
我假设link_id可以有两个,既然没有id列,我们就临时凑合一下

WITH r AS
(SELECT row_number() OVER() as id,
       link_ids,
       length from Table1)
SELECT DISTINCT ON (id) link_ids,
       unnest(length) 
FROM r 
ORDER BY id, length;

假设表名为t,并且link_id的每个值都是唯一的

select link_ids, min(len)
from (select link_ids, unnest(length) as len from t) as t
group by link_ids;

 link_ids | min
----------+-----
 {2,5}    |   0
 {1,4}    |   1
假设一张桌子像:

创建表tbl link_ids int[]主键-对于PK来说是奇数 ,长度int[] ,检查长度“{}”:int[]-排除长度为null和空的情况 ; 查询Postgres 9.3或更高版本:

选择链接ID,最小长度为最小长度 从tbl t开始,未检测长度长度len-隐式横向连接 分组1例; 或者创建一个小函数Postgres 8.4+:

创建或替换函数arr_minanyarray 返回任意元素语言sql不可变并行安全 '从unnest$1 i中选择mini'; 仅在Postgres 9.6或更高版本中添加并行安全。然后:

从t中选择link_id,arr_minlength作为minu length; 该函数可以内联,速度很快

或者,对于一般长度的整数数组,使用附加模块及其内置的Postgres 8.3+:

选择链接ID,sortlength[1]作为t的最小长度;
对Erwin的答案稍加补充——有时带有unnest的子查询甚至比横向连接更便宜

我使用了Erwin答案中的表格定义并填写了它:

t=# insert into t select '{1}'::int[]||g,'{1}'::int[]||g from generate_series(1,9999,1) g;
INSERT 0 9999
t=# select * from t order by ctid desc limit 1;
 link_ids |  length
----------+----------
 {1,9999} | {1,9999}
(1 row)
然后分析横向连接:

t=# explain analyze select link_ids,max(r) from t, unnest(length) r where link_ids = '{1,9999}' group by 1;
                                                      QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
 GroupAggregate  (cost=0.29..4.81 rows=1 width=33) (actual time=0.030..0.030 rows=1 loops=1)
   ->  Nested Loop  (cost=0.29..4.30 rows=100 width=33) (actual time=0.025..0.027 rows=2 loops=1)
         ->  Index Scan using t_pkey on t  (cost=0.29..2.30 rows=1 width=58) (actual time=0.015..0.016 rows=1 loops=1)
               Index Cond: (link_ids = '{1,9999}'::integer[])
         ->  Function Scan on unnest r  (cost=0.00..1.00 rows=100 width=4) (actual time=0.007..0.007 rows=2 loops=1)
 Total runtime: 0.059 ms
(6 rows)
然后尝试子查询:

t=# explain analyze select link_ids, (select max(r) from unnest(length) r) from t where link_ids = '{1,9999}';
                                                      QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
 Index Scan using t_pkey on t  (cost=0.29..3.56 rows=1 width=58) (actual time=0.030..0.031 rows=1 loops=1)
   Index Cond: (link_ids = '{1,9999}'::integer[])
   SubPlan 1
     ->  Aggregate  (cost=1.25..1.26 rows=1 width=4) (actual time=0.011..0.011 rows=1 loops=1)
           ->  Function Scan on unnest r  (cost=0.00..1.00 rows=100 width=4) (actual time=0.008..0.008 rows=2 loops=1)
 Total runtime: 0.060 ms
(6 rows)
最后,确保结果相同:

t=# select link_ids, (select max(r) from unnest(length) r) 
from t 
where link_ids = '{1,9999}';
 link_ids | max
----------+------
 {1,9999} | 9999
(1 row)

t=# select link_ids,max(r) 
from t, unnest(length) r 
where link_ids = '{1,9999}' 
group by 1;
 link_ids | max
----------+------
 {1,9999} | 9999
(1 row)
对于阵列的最小值:

SELECT max(x) from unnest(array_name) as x;

为什么列是数组?这看起来像是一个非常糟糕的模式设计。为了放大@Falmari的评论,有一组称为范式的形式规则,描述了关系数据库的模式应该是什么样子,以防止出现很多问题-至少符合前三个被认为是明智的-您的模式不符合前三个一个是因为表中的单元格不存储原子值。你应该用表格来存储列表。我熟悉普通表格。这是我想进一步处理的递归查询的结果。您应该编写递归查询,以便它提供行而不是数组。您的Postgres版本对于这个问题至关重要。另外:列可以为空吗?数组是否可以为空?链接ID是唯一的吗?数组是否按照您的示例所示的升序排列?如果使用的是实际表,请发布表定义。否则,最好发布递归查询:可能有更好的解决方案。加上基础表的表定义。很好!横向连接对我帮助很大。在我的例子中避免了很多子查询。谢谢。