In PostgreSQL possiamo usare STRING_AGG()
funzione per restituire colonne da una query come un elenco delimitato.
Sintassi
La sintassi è questa:
string_agg ( value text, delimiter text ) → text
string_agg ( value bytea, delimiter bytea ) → bytea
Possiamo anche usare il ORDER BY
clausola e un DISTINCT
clausola dall'interno di questa funzione, che influisce sull'output della funzione. Maggiori informazioni su questo di seguito.
Esempio
Supponiamo di eseguire la seguente query:
SELECT PetName
FROM Pets;
E otteniamo il seguente risultato:
+---------+ | petname | +---------+ | Fluffy | | Fetch | | Scratch | | Wag | | Tweet | | Fluffy | | Bark | | Meow | +---------+ (8 rows)
Possiamo usare STRING_AGG()
per restituire tutte quelle righe come un elenco delimitato.
Per fare ciò, passa il PetName
colonna come primo argomento e il nostro delimitatore scelto come secondo argomento:
SELECT STRING_AGG(PetName, ',')
FROM Pets;
Risultato:
+-------------------------------------------------+ | string_agg | +-------------------------------------------------+ | Fluffy,Fetch,Scratch,Wag,Tweet,Fluffy,Bark,Meow | +-------------------------------------------------+ (1 row)
Cambiare il delimitatore
Nell'esempio precedente, ho scelto una virgola come delimitatore. Eccolo con un delimitatore diverso:
SELECT STRING_AGG(PetName, '-')
FROM Pets;
Risultato:
Fluffy-Fetch-Scratch-Wag-Tweet-Fluffy-Bark-Meow
Possiamo anche usare una stringa vuota per rimuovere tutti i separatori (in modo che i valori siano concatenati):
SELECT STRING_AGG(PetName, '')
FROM Pets;
E otteniamo il seguente risultato:
FluffyFetchScratchWagTweetFluffyBarkMeow
Ordinamento
Possiamo usare il ORDER BY
clausola all'interno di STRING_AGG()
funzione per ordinare il proprio output:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName ASC) FROM Pets;
Risultato:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Era in ordine crescente.
Eccolo in ordine decrescente:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName DESC) FROM Pets;
Risultato:
Wag,Tweet,Scratch,Meow,Fluffy,Fluffy,Fetch,Bark
Nota che questo ordina solo l'output di STRING_AGG()
funzione – è completamente indipendente da qualsiasi ordinamento applicato a SELECT
dichiarazione stessa.
Il DISTINCT
Clausola
Possiamo usare il DISTINCT
clausola per restituire valori univoci. In altre parole, se sono presenti valori duplicati, viene restituita una sola occorrenza:
SELECT STRING_AGG(DISTINCT PetName, ',' ORDER BY PetName ASC) FROM Pets;
Risultato:
Bark,Fetch,Fluffy,Meow,Scratch,Tweet,Wag
In questo caso, Fluffy
appare solo una volta. Quando lo eseguiamo senza DISTINCT
clausola, Fluffy
appare due volte:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName ASC) FROM Pets;
Risultato:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Risultati di query raggruppati
Possiamo includere STRING_AGG()
in una query con un GROUP BY
clausola per ottenere un risultato come questo:
SELECT
PetTypeId,
STRING_AGG(PetName, ',' ORDER BY PetName ASC)
FROM Pets
GROUP BY PetTypeId
ORDER BY PetTypeId;
Risultato:
+-----------+-----------------------+ | pettypeid | string_agg | +-----------+-----------------------+ | 1 | Tweet | | 2 | Fluffy,Meow,Scratch | | 3 | Bark,Fetch,Fluffy,Wag | +-----------+-----------------------+
Nel mio database, i nomi dei tipi di animali domestici effettivi sono in un'altra tabella chiamata PetTypes
. Potremmo quindi eseguire un INNER JOIN
su PetTypes
tabella per ottenere i nomi dei tipi di animali domestici effettivi:
SELECT
pt.PetType,
STRING_AGG(p.PetName, ',' ORDER BY p.PetName ASC)
FROM Pets p
INNER JOIN PetTypes pt ON
p.PetTypeId = pt.PetTypeId
GROUP BY pt.PetType
ORDER BY pt.PetType ASC;
Risultato:
+---------+-----------------------+ | pettype | string_agg | +---------+-----------------------+ | Bird | Tweet | | Cat | Fluffy,Meow,Scratch | | Dog | Bark,Fetch,Fluffy,Wag | +---------+-----------------------+