PostgreSQL:获取数组中指定元素的出现次数

时间:2014-10-23 07:47:25

标签: sql arrays postgresql plpgsql

我需要计算数组中指定元素的出现次数,例如:

  

elem_occurrences_count(ARRAY[a,b,c,a,a], a) = 3

     

elem_occurrences_count(ARRAY[a,b,c], d) = 0

PostgreSQL中是否有可用于解决问题的功能?任何帮助表示赞赏。

5 个答案:

答案 0 :(得分:3)

您将需要取消该阵列,然后计算出现次数。

with elements (element) as (
   select unnest(ARRAY['a','b','c','a','a'])
)
select count(*)
from elements
where element = 'a';

这可以很容易地嵌入到函数中:

create or replace function count_elements(elements text[], to_find text)
  returns bigint
as
$body$
  select count(*) 
  from unnest(elements) element 
  where element =  to_find;
$body$
language sql;

更新

自Postgres 9.5以来,这也可以使用array_positions()来完成,select cardinality(array_positions(ARRAY['a','b','c','a','a'], 'a')); 返回找到元素的位置数组。该数组的长度是出现次数:

{{1}}

答案 1 :(得分:1)

9.5 +

现在有一种更简单的方法

SELECT
  sArray,
  c,
  coalesce(array_length( array_positions(sArray, c), 1 ),0) AS count
FROM ( VALUES
  (ARRAY['a','b','c','a','a'], 'a'),
  (ARRAY['a','b','c'], 'd')
) AS t(sArray,c);

   sarray    | c | count 
-------------+---+-------
 {a,b,c,a,a} | a |     3
 {a,b,c}     | d |     0
(2 rows)

答案 2 :(得分:1)

可以通过这个查询找到数组中所有元素的出现:

SELECT count(id), UNNEST(array) as element
FROM myTable 
GROUP BY element;

要计算特定元素的出现次数,例如“c”,请添加 WHERE 子句:

SELECT count(id), UNNEST(array) as element
FROM myTable 
WHERE EXISTS (SELECT * FROM UNNEST(array) AS x WHERE x='c')
GROUP BY element;

答案 3 :(得分:0)

这里有更多通用功能;

CREATE FUNCTION count_array_elements (
  i_elements pg_catalog.anyarray,
  i_element_to_find pg_catalog.anyelement,
  out count bigint
)
RETURNS bigint AS
$body$
BEGIN
  SELECT count(*) INTO count
  FROM unnest(i_elements) u
  WHERE u = i_element_to_find;
END;
$body$
LANGUAGE 'plpgsql'
IMMUTABLE
RETURNS NULL ON NULL INPUT;

通过这种方式,我们可以像下面这样查询;

SELECT * FROM count_array_elements(array [ TRUE, TRUE, FALSE, FALSE, FALSE ], TRUE);

答案 4 :(得分:0)

感谢所有贡献者,我学到了一些东西。 我正在构建此线程中的其他人的工作以及stackoverflow中的其他工作。

我尝试创建一个可以计算数组中所有唯一元素的函数。

我的目标是返回一个json,但似乎你只能返回SETOF。

result of count_element_3

CREATE OR REPLACE FUNCTION count_element_3(str_array text[])
RETURNS setof text
AS
$$
DECLARE
    unique_element_array text[];
    cardinality_array int[];
    retArray text[];
BEGIN
-- Find unique items first
    unique_element_array := array(select distinct unnest(str_array));
    FOR I IN array_lower(unique_element_array, 1)..array_upper(unique_element_array, 1) 
    LOOP
    cardinality_array[I] := (select cardinality(array_positions(str_array, unique_element_array[I])));
    retArray[I] := concat(unique_element_array[I],':',cardinality_array[I]);
    END LOOP;

RETURN QUERY SELECT(retArray::text);
END;
$$
LANGUAGE plpgsql 
VOLATILE 
RETURNS NULL ON NULL INPUT;

with t1 as (SELECT
  sArray,
  c,
  coalesce(array_length( array_positions(sArray, c), 1 ),0) AS count
FROM ( VALUES
  (ARRAY['a','b','c','a','a'], 'a'),
  (ARRAY['a','b','c'], 'd')
) AS t(sArray,c)
)

select sarray, count_element_3(sarray) from t1

    sarray          count_element_3 
    text[]          text
-------------------------------------
    "{a,b,c,a,a}"   "{c:1,a:3,b:1}"
    "{a,b,c}"       "{c:1,a:1,b:1}"
相关问题