I PostgreSQL kan vi bruge STRING_AGG()
funktion til at returnere kolonner fra en forespørgsel som en afgrænset liste.
Syntaks
Syntaksen ser sådan ud:
string_agg ( value text, delimiter text ) → text
string_agg ( value bytea, delimiter bytea ) → bytea
Vi kan også bruge ORDER BY
klausul og en DISTINCT
klausul fra denne funktion, som påvirker outputtet fra funktionen. Mere om dette nedenfor.
Eksempel
Antag, at vi kører følgende forespørgsel:
SELECT PetName
FROM Pets;
Og vi får følgende resultat:
+---------+ | petname | +---------+ | Fluffy | | Fetch | | Scratch | | Wag | | Tweet | | Fluffy | | Bark | | Meow | +---------+ (8 rows)
Vi kan bruge STRING_AGG()
for at returnere alle disse rækker som en afgrænset liste.
For at gøre dette skal du videregive PetName
kolonne som det første argument, og vores valgte skilletegn som det andet argument:
SELECT STRING_AGG(PetName, ',')
FROM Pets;
Resultat:
+-------------------------------------------------+ | string_agg | +-------------------------------------------------+ | Fluffy,Fetch,Scratch,Wag,Tweet,Fluffy,Bark,Meow | +-------------------------------------------------+ (1 row)
Ændring af skilletegn
I det forrige eksempel valgte jeg et komma som afgrænsning. Her er det med en anden afgrænsning:
SELECT STRING_AGG(PetName, '-')
FROM Pets;
Resultat:
Fluffy-Fetch-Scratch-Wag-Tweet-Fluffy-Bark-Meow
Vi kan endda bruge en tom streng til at fjerne alle separatorer (så værdierne er sammenkædet):
SELECT STRING_AGG(PetName, '')
FROM Pets;
Og vi får følgende resultat:
FluffyFetchScratchWagTweetFluffyBarkMeow
Bestilling
Vi kan bruge ORDER BY
klausul i STRING_AGG()
funktion for at bestille sit eget output:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName ASC) FROM Pets;
Resultat:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Det var i stigende rækkefølge.
Her er det i faldende rækkefølge:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName DESC) FROM Pets;
Resultat:
Wag,Tweet,Scratch,Meow,Fluffy,Fluffy,Fetch,Bark
Bemærk, at dette kun sorterer output fra STRING_AGG()
funktion – den er fuldstændig uafhængig af enhver bestilling, der anvendes på SELECT
selve erklæringen.
DISTINCT
Klausul
Vi kan bruge DISTINCT
klausul for at returnere unikke værdier. Med andre ord, hvis der er duplikerede værdier, returneres kun én forekomst:
SELECT STRING_AGG(DISTINCT PetName, ',' ORDER BY PetName ASC) FROM Pets;
Resultat:
Bark,Fetch,Fluffy,Meow,Scratch,Tweet,Wag
I dette tilfælde Fluffy
vises kun én gang. Når vi kører det uden DISTINCT
klausul, Fluffy
vises to gange:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName ASC) FROM Pets;
Resultat:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Resultater af grupperet forespørgsel
Vi kan inkludere STRING_AGG()
i en forespørgsel med en GROUP BY
klausul for at opnå et resultat som dette:
SELECT
PetTypeId,
STRING_AGG(PetName, ',' ORDER BY PetName ASC)
FROM Pets
GROUP BY PetTypeId
ORDER BY PetTypeId;
Resultat:
+-----------+-----------------------+ | pettypeid | string_agg | +-----------+-----------------------+ | 1 | Tweet | | 2 | Fluffy,Meow,Scratch | | 3 | Bark,Fetch,Fluffy,Wag | +-----------+-----------------------+
I min database er de faktiske kæledyrstypenavne i en anden tabel kaldet PetTypes
. Vi kunne derfor køre en INNER JOIN
på PetTypes
tabel for at få de faktiske kæledyrstypenavne:
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;
Resultat:
+---------+-----------------------+ | pettype | string_agg | +---------+-----------------------+ | Bird | Tweet | | Cat | Fluffy,Meow,Scratch | | Dog | Bark,Fetch,Fluffy,Wag | +---------+-----------------------+