MySQL har en GROUP_CONCAT()
funktion som gör att vi kan returnera kolumner från en fråga som en avgränsad lista.
Den returnerar ett strängresultat med den sammanlänkade icke-NULL
värden från en grupp.
Syntax
Syntaxen ser ut så här:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr}
[ASC | DESC] [,col_name ...]]
[SEPARATOR str_val])
Exempel
Anta att vi kör följande fråga:
SELECT PetName
FROM Pets;
Och vi får följande resultat:
+---------+ | PetName | +---------+ | Fluffy | | Fetch | | Scratch | | Wag | | Tweet | | Fluffy | | Bark | | Meow | +---------+ 8 rows in set (0.00 sec)
Vi kan använda GROUP_CONCAT()
för att returnera alla dessa rader som en avgränsad lista.
För att göra detta måste vi skicka PetName
kolumnen som ett argument till GROUP_CONCAT()
funktion:
SELECT GROUP_CONCAT(PetName)
FROM Pets;
Resultat:
+-------------------------------------------------+ | GROUP_CONCAT(PetName) | +-------------------------------------------------+ | Fluffy,Fetch,Scratch,Wag,Tweet,Fluffy,Bark,Meow | +-------------------------------------------------+ 1 row in set (0.01 sec)
Beställer
Vi kan använda ORDER BY
sats för att beställa utgången av denna funktion:
SELECT GROUP_CONCAT(PetName ORDER BY PetName ASC)
FROM Pets;
Resultat:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Observera att detta bara sorterar utdata från GROUP_CONCAT()
funktion – den är helt oberoende av eventuell ordning som tillämpas på SELECT
själva uttalandet.
DISTINCT
Klausul
Vi kan använda DISTINCT
klausul för att returnera unika värden. Med andra ord, om det finns dubbletter av värden, returneras endast en förekomst:
SELECT GROUP_CONCAT(DISTINCT PetName ORDER BY PetName ASC)
FROM Pets;
Resultat:
Bark,Fetch,Fluffy,Meow,Scratch,Tweet,Wag
I det här fallet, Fluffy
visas bara en gång. När vi kör det utan DISTINCT
klausul, Fluffy
visas två gånger.
Ändra avskiljaren
Som standard använder listan kommatecken som avgränsare. Men vi kan ändra detta om vi vill:
SELECT GROUP_CONCAT(PetName SEPARATOR '-')
FROM Pets;
Resultat:
Fluffy-Fetch-Scratch-Wag-Tweet-Fluffy-Bark-Meow
Vi kan till och med använda en tom sträng för att ta bort alla avgränsare (så att värdena sammanfogas):
SELECT GROUP_CONCAT(PetName SEPARATOR '')
FROM Pets;
Och vi får följande resultat:
FluffyFetchScratchWagTweetFluffyBarkMeow
Grupperade frågeresultat
Vi kan inkludera GROUP_CONCAT()
i en fråga med en GROUP BY
klausul för att uppnå ett resultat som detta:
SELECT
PetTypeId,
GROUP_CONCAT(PetName ORDER BY PetName ASC)
FROM Pets
GROUP BY PetTypeId
ORDER BY PetTypeId;
Resultat:
+-----------+--------------------------------------------+ | PetTypeId | GROUP_CONCAT(PetName ORDER BY PetName ASC) | +-----------+--------------------------------------------+ | 1 | Tweet | | 2 | Fluffy,Meow,Scratch | | 3 | Bark,Fetch,Fluffy,Wag | +-----------+--------------------------------------------+
I min databas finns de faktiska husdjurstypnamnen i en annan tabell som heter PetTypes
. Vi kunde därför köra en INNER JOIN
på PetTypes
tabell för att få de faktiska husdjurstypnamnen:
SELECT
pt.PetType,
GROUP_CONCAT(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 | GROUP_CONCAT(p.PetName ORDER BY p.PetName ASC) | +---------+------------------------------------------------+ | Bird | Tweet | | Cat | Fluffy,Meow,Scratch | | Dog | Bark,Fetch,Fluffy,Wag | +---------+------------------------------------------------+
Längdbegränsningar
GROUP_CONCAT()
's utdata trunkeras till den maximala längden som ges av group_concat_max_len
systemvariabel, som har ett standardvärde på 1024
. Värdet kan ställas in högre, även om den effektiva maximala längden för returvärdet begränsas av värdet max_allowed_packet
.
Du kan kontrollera det aktuella värdet så här:
SHOW VARIABLES LIKE '%group_concat%';
Syntaxen för att ändra detta värde ser ut som följer:
SET [GLOBAL | SESSION] group_concat_max_len = val;
Där val
är ett heltal utan tecken.