postgresql 排序数组元素

qzwqbdag  于 2023-02-04  发布在  PostgreSQL
关注(0)|答案(7)|浏览(644)

我想写一个存储过程,它获取一个数组作为输入参数,对该数组排序并返回排序后的数组。

rqmkfv5c

rqmkfv5c1#

毫无疑问,对整数数组排序的最佳方法是使用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稍快的版本替换了我的版本)。

euoag5mw

euoag5mw2#

在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

和array_agg如下所示:

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

但它会更慢。
您还可以在pl/pgsql或任何其他可以插入postgres的语言中实现任何排序算法。

htrmnn0y

htrmnn0y3#

只需使用函数unnest():

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

参见第页文档中的array functions

ccgok5k5

ccgok5k54#

这对我在www.example.com上很有效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的了解要多得多,有一个更好的答案。如果可能的话,也请投票删除我的答案。

ttygqcqt

ttygqcqt5#

非常好的展览PostgreSQL的特点是一般程序排序由大卫费特。

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

avwztpqn6#

如果您正在寻找一个可以跨任何数据类型工作的解决方案,我建议您采用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
9rnv2umw

9rnv2umw7#

我很惊讶没人提到控制室的操作员

select array[1,2,3] <@ array[2,1,3] and array[1,2,3] @> array[2,1,3];
 ?column?
══════════
 t
(1 row)

请注意,这要求数组的所有元素必须是唯一的。
(If a包含B且b包含a,如果所有元素都是唯一的,则它们必须相同)

相关问题