2014-12-10 8 views
5

Ist es möglich, die Anzahl der Elemente in der folgenden string_agg Funktion zu begrenzen?PostgreSQL - string_agg mit begrenzter Anzahl von Elementen

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

Können Sie den Rest der Abfrage zur Verfügung stellen? Sie können Ihre Ergebnisse mit einer Unterabfrage und 'row_number' erreichen, aber Sie können es mit' limit' alleine arbeiten lassen. – sgeddes

+0

Sie können die Funktion nicht selbst einschränken, aber erweitern Sie das Problem, warum brauchen Sie das? Vielleicht finden wir einen anderen Weg. –

+0

Können Sie diese Frage klären: Wollen Sie die * Größe * oder die * Anzahl der Elemente * begrenzen? –

Antwort

7

Ich bin mir nicht bewusst, dass Sie es in der string_agg() Funktion einschränken. Sie können es auf andere Weise begrenzen:

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

Dann können Sie tun:

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 
+0

Danke. Ich bevorzuge es, weitere Unterabfragen zu vermeiden. Ich werde wahrscheinlich vermeiden, string_agg zu verwenden. – nickbusted

5

Um limit the number of elements in the following string_agg() verwenden LIMIT in einer Unterabfrage:

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;

Beachten Sie, dass die Unterabfrage nicht a Problem für die Leistung überhaupt. Im Gegensatz ist dies in der Regel schneller, auch wenn Sie keine maximale Anzahl mit LIMIT auferlegen, weil die Groupwise DISTINCT in der Aggregatfunktion teurer ist als in einer Unterabfrage für alle Zeilen gleichzeitig.

Oder zu bekommen die "100 am häufigsten Tags":

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

Es gibt zwei weitere Möglichkeiten.

1) ein Array von Reihen bilden, begrenzen, und dann in String verketten:

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

("array [1: 3]" bedeutet: nehmen Elemente aus 1 bis 3 aus array)

2) verketten Zeilen in String ohne Limit, dann „substring“ verwenden es trimmen:

string_agg(distinct(tag),',') 

Wenn Sie, dass Ihr „Tag“ -Feld weiß nicht , Zeichen enthalten, dann können Sie den gesamten Text auswählen, bevor n-te Auftreten Ihrer ,

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

Diese Teilzeichenfolge wählt 3 oder weniger Strings geteilt durch ,