I MySQL kan du returnere dine forespørgselsresultater som en kommasepareret liste ved at bruge GROUP_CONCAT()
funktion.
GROUP_CONCAT()
funktion blev bygget specifikt med det formål at sammenkæde en forespørgsels resultatsæt til en liste adskilt af enten et komma eller en afgrænsning efter eget valg.
Denne artikel giver eksempler på, hvordan det hele fungerer.
Dataene
Lad os først bruge følgende data i vores første par eksempler:
USE Solutions; SELECT TaskName FROM Tasks;
Resultat:
+-------------------+ | TaskName | +-------------------+ | Do garden | | Feed cats | | Paint roof | | Take dog for walk | | Relax | | Feed cats | +-------------------+
Grundlæggende eksempel
Her er et grundlæggende eksempel til at demonstrere GROUP_CONCAT()
funktion:
SELECT GROUP_CONCAT(TaskName) FROM Tasks;
Resultat:
+------------------------------------------------------------------+ | GROUP_CONCAT(TaskName) | +------------------------------------------------------------------+ | Do garden,Feed cats,Paint roof,Take dog for walk,Relax,Feed cats | +------------------------------------------------------------------+
Som du kan se, er hver række fra resultatsættet blevet sammenkædet i en enkelt række. Som standard er listen adskilt af et komma.
Bemærk, at der er begrænsninger på, hvor lang denne liste kan være. Mere om dette senere i artiklen.
Eksempel – DISTINCT
Du kan bruge DISTINCT
for at fjerne dubletter (så dubletter bliver én post).
Eksempel:
SELECT GROUP_CONCAT(DISTINCT TaskName) FROM Tasks;
Resultat:
+--------------------------------------------------------+ | GROUP_CONCAT(DISTINCT TaskName) | +--------------------------------------------------------+ | Do garden,Feed cats,Paint roof,Relax,Take dog for walk | +--------------------------------------------------------+
Så i dette tilfælde er "Foderkatte" kun opført én gang, hvorimod det blev opført to gange i det foregående eksempel.
Eksempel – BESTIL EFTER
Du kan bruge ORDER BY
for at sortere resultaterne efter en given kolonne.
Eksempel:
SELECT GROUP_CONCAT(DISTINCT TaskName ORDER BY TaskName DESC) FROM Tasks;
Resultat:
+--------------------------------------------------------+ | GROUP_CONCAT(DISTINCT TaskName ORDER BY TaskName DESC) | +--------------------------------------------------------+ | Take dog for walk,Relax,Paint roof,Feed cats,Do garden | +--------------------------------------------------------+
Så i dette tilfælde bruger jeg DESC
for at angive, at det skal være i faldende rækkefølge. Den alternative (og standard) værdi er ASC
for stigende.
Eksempel – Angiv en afgrænsning
Som standard er listen en kommasepareret liste. Du kan dog angive en afgrænsning efter eget valg, hvis det kræves.
For at gøre dette skal du bruge SEPARATOR
efterfulgt af strengen literal værdi, der skal indsættes mellem gruppeværdier.
Eksempel:
SELECT GROUP_CONCAT(DISTINCT TaskName SEPARATOR ' + ') FROM Tasks;
Resultat:
+----------------------------------------------------------------+ | GROUP_CONCAT(DISTINCT TaskName SEPARATOR ' + ') | +----------------------------------------------------------------+ | Do garden + Feed cats + Paint roof + Relax + Take dog for walk | +----------------------------------------------------------------+
Eksempel – Kombination af kolonner
Du kan også sammenkæde kolonner og angive deres egen separator ved at angive en bogstavlig strengværdi.
Eksempel:
SELECT GROUP_CONCAT(TaskId, ') ', TaskName SEPARATOR ' ') FROM Tasks;
Resultat:
+------------------------------------------------------------------------------------+ | GROUP_CONCAT(TaskId, ') ', TaskName SEPARATOR ' ') | +------------------------------------------------------------------------------------+ | 1) Do garden 2) Feed cats 3) Paint roof 4) Take dog for walk 5) Relax 6) Feed cats | +------------------------------------------------------------------------------------+
I dette eksempel returnerer vi både TaskId
kolonnen og TaskName
kolonne, adskilt af en afsluttende parentes og et mellemrum. Vi bruger også SEPARATOR
argument for at specificere, at afgrænsningstegnet, der skal bruges mellem hver (sammenkædet) række, skal være et mellemrum (i stedet for standardkommaet).
Grupperte resultater
GROUP_CONCAT()
funktion kan være nyttig til lejligheder, hvor du ønsker at give en liste over resultater, grupperet efter en anden kolonne.
For eksempel vil du måske have en liste over kunstnere med hver kunstner efterfulgt af en liste over album, de har udgivet.
For at demonstrere dette, lad os sige, at vi har en database med to tabeller; Artists
og Albums
. Der er et til mange forhold mellem disse tabeller. For hver kunstner kan der være mange album.
Så en almindelig forespørgsel, der forbinder begge tabeller, kan se sådan ud:
USE Music; SELECT ar.ArtistName, al.AlbumName FROM Artists ar INNER JOIN Albums al ON ar.ArtistId = al.ArtistId;
Resultat:
+------------------------+--------------------------+ | ArtistName | AlbumName | +------------------------+--------------------------+ | Iron Maiden | Powerslave | | AC/DC | Powerage | | Jim Reeves | Singing Down the Lane | | Devin Townsend | Ziltoid the Omniscient | | Devin Townsend | Casualties of Cool | | Devin Townsend | Epicloud | | Iron Maiden | Somewhere in Time | | Iron Maiden | Piece of Mind | | Iron Maiden | Killers | | Iron Maiden | No Prayer for the Dying | | The Script | No Sound Without Silence | | Buddy Rich | Big Swing Face | | Michael Learns to Rock | Blue Night | | Michael Learns to Rock | Eternity | | Michael Learns to Rock | Scandinavia | | Tom Jones | Long Lost Suitcase | | Tom Jones | Praise and Blame | | Tom Jones | Along Came Jones | | Allan Holdsworth | All Night Wrong | | Allan Holdsworth | The Sixteen Men of Tain | +------------------------+--------------------------+
Som du kan se, når du bruger dette format, hvis en kunstner har mere end ét album, er den kunstner opført flere gange – én gang for hvert album.
Vi kunne ændre denne forespørgsel, så hver kunstner kun er opført én gang. Hvis en kunstner har mere end ét album, vises alle album i et enkelt felt på en kommasepareret liste. Vi kan gøre dette takket være GROUP_CONCAT()
funktion.
Eksempel:
USE Music; SELECT ar.ArtistName, GROUP_CONCAT(al.AlbumName) FROM Artists ar INNER JOIN Albums al ON ar.ArtistId = al.ArtistId GROUP BY ArtistName;
Resultat:
+------------------------+----------------------------------------------------------------------------+ | ArtistName | GROUP_CONCAT(al.AlbumName) | +------------------------+----------------------------------------------------------------------------+ | AC/DC | Powerage | | Allan Holdsworth | All Night Wrong,The Sixteen Men of Tain | | Buddy Rich | Big Swing Face | | Devin Townsend | Epicloud,Ziltoid the Omniscient,Casualties of Cool | | Iron Maiden | Somewhere in Time,Piece of Mind,Powerslave,Killers,No Prayer for the Dying | | Jim Reeves | Singing Down the Lane | | Michael Learns to Rock | Eternity,Scandinavia,Blue Night | | The Script | No Sound Without Silence | | Tom Jones | Long Lost Suitcase,Praise and Blame,Along Came Jones | +------------------------+----------------------------------------------------------------------------+
Vær forsigtig med længden!
En vigtig ting, du skal være opmærksom på, når du bruger GROUP_CONCAT()
er, at resultatet er afkortet til den maksimale længde, der er givet af group_concat_max_len
systemvariabel, som har en standardværdi på 1024
.
Denne variabels værdi kan indstilles højere ved at bruge følgende syntaks:
SET [GLOBAL | SESSION] group_concat_max_len = val;
Hvor val
er et heltal uden fortegn.
Bemærk dog, at den effektive maksimale længde af returværdien i sig selv er begrænset af værdien max_allowed_packet
.