PostgreSQL - string_agg 元素数量有限

问题描述 投票:0回答:5

是否可以限制以下

string_agg
函数中的元素数量?

 string_agg(distinct(tag),', ')
sql postgresql aggregate-functions
5个回答
26
投票

还有两种方法。

  1. 从行创建一个数组,对其进行限制,然后连接成字符串:

    SELECT array_to_string((array_agg(DISTINCT tag))[1:3], ', ') FROM tbl
    

(“array[1:3]”表示:从数组中取出1到3的项)

  1. 将行无限制地连接成字符串,然后使用“子字符串”对其进行修剪:

    string_agg(distinct(tag),',')
    

如果您知道“标签”字段不能包含

,
字符,那么您可以选择第 n 次出现
,

之前的所有文本
SELECT substring(
string_agg(DISTINCT tag, ',') || ','
from '(?:[^,]+,){1,3}')
FROM tbl

此子字符串将选择 3 个或更少的字符串除以

,
。要排除尾随
,
,只需添加
rtrim
:

SELECT rtrim(substring(
string_agg(DISTINCT tag, ',') || ','
from '(?:[^,]+,){1,3}'), ',')
FROM test

16
投票

要“限制以下 string_agg()

”中的元素数量
,请在子查询中使用 LIMIT

SELECT string_agg(tag, ', ') AS tags FROM ( SELECT DISTINCT tag FROM tbl -- ORDER BY tag -- optionally order to get deterministic result LIMIT 123 -- add your limit here ) sub;
子查询对于性能来说完全没有问题。 

相反,即使您没有使用 LIMIT 强加最大数量,这通常也更快

,因为聚合函数中的按组 
DISTINCT
 比在子查询中执行更昂贵一次所有行。

或者,获取

“100 个最常见的标签”:

SELECT string_agg(tag, ', ') AS tags FROM ( SELECT tag FROM tbl GROUP BY tag ORDER BY count(*) DESC LIMIT 100 ) sub;
    

10
投票
我不知道你可以在

string_agg()

功能中限制它。您可以通过其他方式限制它:

select postid, string_agg(distinct(tag), ', ') from table t group by postid

然后你可以这样做:

select postid, string_agg(distinct (case when seqnum <= 10 then tag end), ', ') from (select t.*, dense_rank() over (partition by postid order by tag) as seqnum from table t ) t group by postid
    

3
投票

string_agg

 子句嵌套在 
split_part
 中,包括作为第二个参数的分隔符,以及作为最后一个参数的所需元素数量。像这样:

split_part(string_agg(distinct(tag),', '), ', ', 1)
    

0
投票
使用IN进行过滤

像这样:

Select primaryID, String_Agg(email, '|') As Email From contacts Where contactID In (Select filter.contactID From contacts filter Where filter.primaryID = contacts.primaryID Order By filter.contactID) Group By primaryID;
    
© www.soinside.com 2019 - 2024. All rights reserved.