Postgresql 排序数组元素
我想编写一个存储过程,获取一个数组作为输入参数,并对该数组进行排序,然后返回排序后的数组Postgresql 排序数组元素,postgresql,Postgresql,我想编写一个存储过程,获取一个数组作为输入参数,并对该数组进行排序,然后返回排序后的数组 请帮忙。只需使用unnest()函数即可: 请参阅Pg文档中的。在PostrgreSQL 8.4及更高版本中,您可以使用: select array_agg(x) from (select unnest(ARRAY[1,5,3,7,2]) AS x order by x) as _; 但不会很快 在较老的Postgres中,您可以像这样实现unnest CREATE OR REPLACE FUNCTIO
请帮忙。只需使用unnest()函数即可:
请参阅Pg文档中的。在PostrgreSQL 8.4及更高版本中,您可以使用:
select array_agg(x) from (select unnest(ARRAY[1,5,3,7,2]) AS x order by x) as _;
但不会很快
在较老的Postgres中,您可以像这样实现unnest
CREATE OR REPLACE FUNCTION unnest(anyarray)
RETURNS SETOF anyelement AS
$BODY$
SELECT $1[i] FROM
generate_series(array_lower($1,1),
array_upper($1,1)) i;
$BODY$
LANGUAGE 'sql' IMMUTABLE
数组_agg如下所示:
CREATE AGGREGATE array_agg (
sfunc = array_append,
basetype = anyelement,
stype = anyarray,
initcond = '{}'
);
但速度会更慢
您还可以用pl/pgsql或任何其他可以插入postgres的语言实现任何排序算法
请看克雷格的答案,因为他对博士后的知识更为渊博,并且有更好的答案。如果可能的话,请投票删除我的答案。非常好地展示PostgreSQL的功能是David Fetter排序的一般程序
CREATE OR REPLACE FUNCTION array_sort (ANYARRAY)
RETURNS ANYARRAY LANGUAGE SQL
AS $$
SELECT ARRAY(
SELECT $1[s.i] AS "foo"
FROM
generate_series(array_lower($1,1), array_upper($1,1)) AS s(i)
ORDER BY foo
);
$$;
对整数数组进行排序的最佳方法无疑是使用,这比任何SQL公式都快得多:
CREATE EXTENSION intarray;
SELECT sort( ARRAY[4,3,2,1] );
适用于任何数组类型的函数为:
CREATE OR REPLACE FUNCTION array_sort (ANYARRAY)
RETURNS ANYARRAY LANGUAGE SQL
AS $$
SELECT ARRAY(SELECT unnest($1) ORDER BY 1)
$$;
(我已将我的版本替换为其他地方讨论后的版本)。如果您正在寻找一种可以跨任何数据类型工作的解决方案,我建议您采用在中列出的方法 本质上,您可以创建一个存储过程(下面的代码)来为您执行排序,您所需要做的就是将数组传递给该过程,以便对其进行适当排序 我还包括了一个不需要使用存储过程的实现,如果您希望查询更具可移植性的话 创建存储过程
DROP FUNCTION IF EXISTS array_sort(anyarray);
CREATE FUNCTION
array_sort(
array_vals_to_sort anyarray
)
RETURNS TABLE (
sorted_array anyarray
)
AS $BODY$
BEGIN
RETURN QUERY SELECT
ARRAY_AGG(val) AS sorted_array
FROM
(
SELECT
UNNEST(array_vals_to_sort) AS val
ORDER BY
val
) AS sorted_vals
;
END;
$BODY$
LANGUAGE plpgsql;
-- The following will return: {1,2,3,4}
SELECT ARRAY_SORT(ARRAY[4,3,2,1]);
-- The following will return: {in,is,it,on,up}
SELECT ARRAY_SORT(ARRAY['up','on','it','is','in']);
排序数组值(适用于任何数组数据类型)
不使用存储过程对数组值进行排序
DROP FUNCTION IF EXISTS array_sort(anyarray);
CREATE FUNCTION
array_sort(
array_vals_to_sort anyarray
)
RETURNS TABLE (
sorted_array anyarray
)
AS $BODY$
BEGIN
RETURN QUERY SELECT
ARRAY_AGG(val) AS sorted_array
FROM
(
SELECT
UNNEST(array_vals_to_sort) AS val
ORDER BY
val
) AS sorted_vals
;
END;
$BODY$
LANGUAGE plpgsql;
-- The following will return: {1,2,3,4}
SELECT ARRAY_SORT(ARRAY[4,3,2,1]);
-- The following will return: {in,is,it,on,up}
SELECT ARRAY_SORT(ARRAY['up','on','it','is','in']);
在以下查询中,只需将数组[4,3,2,1]
替换为返回数组的数组或查询:
WITH
sorted_vals AS (
SELECT
UNNEST(ARRAY[4,3,2,1]) AS val
ORDER BY
val
)
SELECT
ARRAY_AGG(val) AS sorted_array
FROM
sorted_vals
。。。或者
SELECT
ARRAY_AGG(vals.val) AS sorted_arr
FROM (
SELECT
UNNEST(ARRAY[4,3,2,1]) AS val
ORDER BY
val
) AS vals
@MartijnPieter注意到它与我的答案是一样的,但我在一年前回答并引用了我从何处得到的答案。@AdamGent:我想我在第一个答案队列中找到了它,只是重新格式化了SQL以使其可读。换句话说,除了不可读的格式之外,我没有任何上下文。最快的方法是
intarray
contrib模块中的sort
函数。我用一些更现代的技术更新了那篇wiki文章,所以请使用文章中的代码(或查看我的答案),不是这里显示的旧答案。Craig我投票删除了我的答案,但由于某些原因,我无法自行终止;)。因此,我做了一个注释以查看您的答案。如果我没有错,那么上面的array\u sort()
函数应该在第二个$$
之后定义为稳定的
(或者可能是不可变的
)标记。其他程序员可能会查看这些波动性标签,以获取关于给定函数如何工作的提示<代码>语言SQL-函数(通常)由Postgres内联,但添加标签没有任何害处。请记住,Unest
将取消对数组的所有级别的测试:因此,如果尝试对数组进行排序,则会得到意外的结果:数组的形状保持不变,但是这些值是单独排序的,不是作为子数组。嗨,bigint没有类似的扩展?它更长,但比Craig的解决方案好吗?我不确定我是否理解你问题的缩进。。是否对您的实现“更好”由您决定。Craig提供了一个5行工作解决方案。差不多一年后,您添加了一个答案,其中包含了一个更长的解决方案。所以我想你的解决方案一定是更好的,或者在某些情况下有效,而另一个则不行。我是(Postgre)SQL新手,所以我无法判断,所以我问:)我还没有进行压力测试来比较我列出的方法和克雷格的方法。。如果有机会,我可能会这么做。:)我确实补充说,排序也可以在不需要创建存储过程的情况下执行,而存储过程对某些人来说可能很有用。不一定是压力测试,但可能是“设计”或其他方面。但如果你不知道,没问题,这只是另一个解决方案,也许其他人稍后会对其中一个发表评论。(