我需要计算数组中指定元素的出现次数,例如:
elem_occurrences_count(ARRAY[a,b,c,a,a], a) = 3
elem_occurrences_count(ARRAY[a,b,c], d) = 0
PostgreSQL中是否有可用于解决问题的功能?任何帮助表示赞赏。
答案 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)
现在有一种更简单的方法
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。
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}"