数组元素计数
来自 PostgreSQL 维基
跳转到导航跳转到搜索作者:Emanuel "3manuek"
如果你使用的是 PostgreSQL 8.3 或更低版本,你需要添加 unnest() 函数来将数组转换为一组行。
函数
CREATE FUNCTION count_elements(text[]) RETURNS text AS $BODY$
select string_agg(i || ':' || c, ' ' ) from (select i, count(*) c FROM (select unnest($1::text[]) i) i group by i order by c desc) foo;
$BODY$
LANGUAGE SQL;
基本测试
postgres=# select count_elements('{1,2,3,4,2,1,2,3,4,5,3,1,2,3,43,1,2,3}'::text[]); -[ RECORD 1 ]--+------------------------------ count_elements | 3:5 2:5 1:4 4:2 5:1 43:1
你可以使用特定数据类型(例如整数或日期)来大幅改进之前的函数,而不是将其强制转换为文本(这将提高 CPU 占用率)。
最棒的是,你可以与 array_agg 结合使用,例如:
postgres=# create table da_values as select round(random()*40) val from generate_series(1,100);
SELECT 100
postgres=# select array_agg(val) from da_values ;
{33,25,23,6,9,5,17,18,36,28,23,23,40,21,13,12,23,30,38,30,14,10,27,24,22,13,1,18,0,3,28,33,28,12,40,37,17,17,15,13,5,38,36,4,19,8,16,2,38,14,32,12,24,19,36,6,32,37,24,32,1,12,25,29,24,25,26,1,2,1,13,6,38,9,11,17,18,27,18,16,2,10,28,25,29,24,31,21,21,15,13,22,27,38,11,10,23,37,11,25}
postgres=# select count_elements(array_agg(val::text)) from da_values ;
count_elements
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
25:5 38:5 13:5 23:5 24:5 1:4 12:4 18:4 28:4 17:4 21:3 2:3 37:3 6:3 11:3 10:3 36:3 27:3 32:3 15:2 40:2 16:2 33:2 22:2 5:2 29:2 9:2 14:2 19:2 30:2 26:1 31:1 4:1 3:1 0:1 8:1
(1 row)
如果你创建一个 count_elements 函数来接收 int[] 而不是 text[],则在 array_agg 之前不需要强制转换参数。这非常重要,因为这是一个基本示例代码,但如果你打算认真运行它,则 *应该* 遵守类型。
你可以添加的其他内容是“标签”,例如:在 count_elements 函数内的 string_agg 函数中使用 "Element:25, Count:5"。