数组元素计数

来自 PostgreSQL 维基
跳转到导航跳转到搜索

代码片段

数组元素计数

适用于 PostgreSQL

任何版本

编写语言

SQL

依赖

作者: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"。

参见

数组范围 数组中位数