2015-02-05 490 views
3

使用的是Postgres 9.3 ...Postgres:在int数组中寻找最大值?

是否有人可以解释为什么我不能在嵌套的阵列上直接使用最多的功能..?

这是我的理解unnest函数返回一个“setof”就像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; 
+0

虽然我写我自己的函数所以解决这个问题,我还是有点困惑。 'unnest'函数返回一组行,并且max函数对一组行进行操作。有没有一个错误,或者有什么我只是没有得到? – user2259963 2015-02-06 17:35:48

+1

是的,有。 'max'是一个聚集,所以它每个元组都有一个输入。它不能像这样输入一个集合。要做你描述你表达它的方式,你需要使用一个子查询,比如'select id,(从unnest(history)x)中选择max(x)作为foo_history'的vmax。 – 2015-02-07 04:42:53

回答

0

您必须记住SQL旨在对数据集进行操作。 MAX函数实际上在第一个例子中起作用,它不会像你期待的那样工作。它将返回匹配的每一行的最大值。

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

+0

看起来像我的_2nd_例子是非常低效的,当你考虑可能有数百万条记录。有点似乎倒退...?也许一个自定义函数是在这种情况下去... – user2259963 2015-02-05 18:35:22

+0

根据您的评论,然后最大的功能应该工作,但这也不起作用。这两个函数都返回...'错误:上下文中调用的set-valued函数不能接受集合' – user2259963 2015-02-05 18:51:29

4

如果您安装了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(x) FROM unnest($1); 
$$ 

和使用:

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

谢谢。写完这些之后,我写了自己的类似函数,返回数组中最大值的位置。然而,这并不是特别困难,我对已经内置的所有其他功能感到惊讶,这种简单的事情尚未得到支持。 – user2259963 2015-02-06 14:52:13

+0

@ user2259963每个功能和实用程序都必须由某人编写,如果有人不太需要它,它就不会被写入。在这个特定的例子中,我会尽快再试一次,自从上次我去了这里之后,我学到了很多关于Pg编码的知识,并且我希望看到它在核心中得到支持。 – 2015-02-07 04:41:12

+0

我明白别人看到的需要。让我知道如果我能帮忙。不幸的是,在我的情况下,我仍然不理解我认为是记录集和行集之间的根本区别。把记录集合变成一个数组很容易 - 但不是相反;如果我们走另一条路,数据将被现有的聚合函数所支持。现在我正在开发一个函数来计算数组子集的标准偏差。 :) – user2259963 2015-02-11 19:23:25

0
在PostgreSQL的9.6和8.4

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

当我们达到9.6时,那会很棒! – user2259963 2017-07-11 19:59:21

+0

我刚刚检查过它可以在PostgreSQL 8.4上运行 – 2017-07-13 14:34:37