对数组元素进行排序

时间:2010-05-26 13:29:04

标签: postgresql

我想编写一个存储过程,它将数组作为输入参数并对该数组进行排序并返回已排序的数组。

请帮助。

6 个答案:

答案 0 :(得分:37)

对整数数组进行排序的最佳方法毫无疑问是使用intarray extension,这将比任何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)
$$;

(我在其他地方讨论后用Pavel's slightly faster one替换了我的版本。)

答案 1 :(得分:14)

在PostrgreSQL 8.4及更高版本中,您可以使用:

select array_agg(x) from (select unnest(ARRAY[1,5,3,7,2]) AS x order by x) as _;

但它不会很快。


在较旧的Postgres中,你可以实现像这样的

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

和array_agg一样:

CREATE AGGREGATE array_agg (
        sfunc = array_append,
        basetype = anyelement,
        stype = anyarray,
        initcond = '{}'
);

但它会更慢。


您还可以使用pl / pgsql或任何其他可插入postgres的语言实现任何排序算法。

答案 2 :(得分:11)

只需使用函数unnest():

SELECT 
    unnest(ARRAY[1,2]) AS x
ORDER BY 
    x DESC;

请参阅Pg文档中的array functions

答案 3 :(得分:7)

这对我来说是http://www.pgsql.cz/index.php/PostgreSQL_SQL_Tricks_I#General_array_sort

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
);
$$;

请参阅克雷格的回答,因为他对Postgres的知识要多得多,并且有更好的答案。如果可能,也投票删除我的答案。

答案 4 :(得分:3)

非常好的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
);
$$;

答案 5 :(得分:1)

如果您正在寻找适用于任何数据类型的解决方案,我建议您采用YouLikeProgramming.com中列出的方法。

基本上,您可以创建一个存储过程(下面的代码)来为您执行排序,您需要做的就是将数组传递给该过程,以便对其进行适当的排序。

我还提供了一个不需要使用存储过程的实现,如果您正在寻找一个更易于移植的查询。

创建存储过程

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']);

在没有存储过程的情况下对数组值进行排序

在以下查询中,只需将ARRAY[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