Arrays Postgres:在整数数组中查找最大值?

Arrays Postgres:在整数数组中查找最大值?,arrays,postgresql,max,postgresql-9.3,Arrays,Postgresql,Max,Postgresql 9.3,使用Postgres 9.3 有人能解释一下为什么我不能在一个不需要的数组上直接使用max函数吗 据我所知,unnest函数返回一组,就像select语句一样。那么为什么这个查询的简短版本不起作用呢?我是在概念上遗漏了什么,还是我的问题与语法有关 table: foo_history: id | history::smallint ----------------------------------- 1 | {10,20,30,50,40} 这不管用 Select id, max(

使用Postgres 9.3

有人能解释一下为什么我不能在一个不需要的数组上直接使用max函数吗

据我所知,unnest函数返回一组,就像select语句一样。那么为什么这个查询的简短版本不起作用呢?我是在概念上遗漏了什么,还是我的问题与语法有关

table: foo_history: 

id | history::smallint
----------------------------------- 
1  |  {10,20,30,50,40}
这不管用

Select id, max(unnest(history)) as vMax from foo_history;
…但这一个是

WITH foo as (
    select id, unnest(history) as history 
    from foo_history
)
Select 
    id, max(history) as vMax
From foo 
Group by id;

您必须记住,SQL是为操作数据集而设计的。在第一个示例中,MAX函数确实起作用,但它并不像您期望的那样起作用。它将返回匹配的每一行的最大值

group by子句按预期工作,因为您现在正在聚合到一个集合中,然后从集合中获取最大值:

如果安装intarray模块,它会提供一些额外的数组运算符,让您可以编写所需的内容,尽管效率有点低:

CREATE EXTENSION intarray;

SELECT id, (sort_desc(history))[1] as vMax
FROM foo_history;
为数组编写最大和最小的函数来添加到intarray中是非常容易的,代码非常简单

否则,您可以只编写一个SQL函数:

CREATE OR REPLACE FUNCTION array_greatest(anyarray)
RETURNS anyelement
LANGUAGE SQL
AS $$
  SELECT max(elements) FROM unnest($1) elements
$$;
并使用:

SELECT id, array_greatest(history) as vMax
FROM foo_history;

在PostgreSQL 9.6和8.4中:

SELECT max(x) FROM unnest(ARRAY[1,2,80,3,15,4]) as x;

我觉得我的第二个例子是非常低效的,如果你认为有数百万的记录。似乎有点倒退。。。??也许在这种情况下,自定义函数是最好的选择……根据您的评论,最好的函数应该可以工作,但也不行。两个函数都返回…'错误:在无法接受集合的上下文中调用的集值函数。写了这个之后,我就编写了自己的类似函数,返回数组中最大值的位置。这并不是特别困难,但是,我对已经内置的所有其他功能感到惊讶,这种简单的功能还不受支持。@user2259963每个函数和实用程序都必须有人编写,如果没有人非常想要它,它就不会被编写。在这个特殊的例子中,我将很快再试一次,自从我上次尝试使用Pg以来,我学到了很多关于Pg编码的知识,我希望看到它在core中得到支持。我感谢其他人看到这一需求。如果我能帮忙,请告诉我。不幸的是,在我的例子中,我仍然不理解我所认为的记录集和行集之间的根本区别。将一个记录集转换成一个数组是非常容易的,但反过来就不行了;如果我们换一种方式,现有的聚合函数将支持数据。现在我正在研究一个函数来计算数组子集的标准偏差:我得到:SQL Error[42703]:Error:x列不存在,其中:SQL函数数组在内联期间最大。你需要在函数的unnest$1后面加一个x,否则它就不起作用了。尽管我写了自己的函数来解决这个问题,我还是有点困惑。“unnest”函数返回一组行,max函数对一组行进行操作。是有虫子还是有什么我不知道的?是的,有。max是一个聚合,因此它对每个元组的一个输入进行操作。它不能把一个集合当作那样的输入。为了实现您描述的表达方式,您需要使用一个子查询,如select id,从UNNESTHISTORX中选择maxx作为从foo_history中选择vmax。当我们达到9.6时,这将非常好!