MySQL má GROUP_CONCAT()
funkce, která nám umožňuje vrátit sloupce z dotazu jako oddělovaný seznam.
Vrátí výsledek řetězce se zřetězeným non-NULL
hodnoty ze skupiny.
Syntaxe
Syntaxe vypadá takto:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr}
[ASC | DESC] [,col_name ...]]
[SEPARATOR str_val])
Příklad
Předpokládejme, že spustíme následující dotaz:
SELECT PetName
FROM Pets;
A dostaneme následující výsledek:
+---------+ | PetName | +---------+ | Fluffy | | Fetch | | Scratch | | Wag | | Tweet | | Fluffy | | Bark | | Meow | +---------+ 8 rows in set (0.00 sec)
Můžeme použít GROUP_CONCAT()
vrátit všechny tyto řádky jako seznam s oddělovači.
K tomu potřebujeme předat PetName
sloupec jako argument pro GROUP_CONCAT()
funkce:
SELECT GROUP_CONCAT(PetName)
FROM Pets;
Výsledek:
+-------------------------------------------------+ | GROUP_CONCAT(PetName) | +-------------------------------------------------+ | Fluffy,Fetch,Scratch,Wag,Tweet,Fluffy,Bark,Meow | +-------------------------------------------------+ 1 row in set (0.01 sec)
Objednávání
Můžeme použít ORDER BY
klauzule k objednání výstupu této funkce:
SELECT GROUP_CONCAT(PetName ORDER BY PetName ASC)
FROM Pets;
Výsledek:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Všimněte si, že toto třídí pouze výstup GROUP_CONCAT()
funkce – je zcela nezávislá na jakémkoli řazení použitém na SELECT
samotné prohlášení.
DISTINCT
Ustanovení
Můžeme použít DISTINCT
klauzule pro vrácení jedinečných hodnot. Jinými slovy, pokud existují duplicitní hodnoty, je vrácen pouze jeden výskyt:
SELECT GROUP_CONCAT(DISTINCT PetName ORDER BY PetName ASC)
FROM Pets;
Výsledek:
Bark,Fetch,Fluffy,Meow,Scratch,Tweet,Wag
V tomto případě Fluffy
se objeví pouze jednou. Když jej spustíme bez DISTINCT
klauzule, Fluffy
se objeví dvakrát.
Změna oddělovače
Ve výchozím nastavení seznam používá jako oddělovač čárku. Ale můžeme to změnit, pokud chceme:
SELECT GROUP_CONCAT(PetName SEPARATOR '-')
FROM Pets;
Výsledek:
Fluffy-Fetch-Scratch-Wag-Tweet-Fluffy-Bark-Meow
Můžeme dokonce použít prázdný řetězec k odstranění všech oddělovačů (takže hodnoty jsou zřetězené):
SELECT GROUP_CONCAT(PetName SEPARATOR '')
FROM Pets;
A dostaneme následující výsledek:
FluffyFetchScratchWagTweetFluffyBarkMeow
Výsledky seskupených dotazů
Můžeme zahrnout GROUP_CONCAT()
v dotazu s GROUP BY
klauzule k dosažení výsledku, jako je tento:
SELECT
PetTypeId,
GROUP_CONCAT(PetName ORDER BY PetName ASC)
FROM Pets
GROUP BY PetTypeId
ORDER BY PetTypeId;
Výsledek:
+-----------+--------------------------------------------+ | PetTypeId | GROUP_CONCAT(PetName ORDER BY PetName ASC) | +-----------+--------------------------------------------+ | 1 | Tweet | | 2 | Fluffy,Meow,Scratch | | 3 | Bark,Fetch,Fluffy,Wag | +-----------+--------------------------------------------+
V mé databázi jsou skutečná jména typů mazlíčků v jiné tabulce nazvané PetTypes
. Mohli bychom tedy spustit INNER JOIN
na PetTypes
tabulka pro získání skutečných jmen typu domácího mazlíčka:
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;
Výsledek:
+---------+------------------------------------------------+ | PetType | GROUP_CONCAT(p.PetName ORDER BY p.PetName ASC) | +---------+------------------------------------------------+ | Bird | Tweet | | Cat | Fluffy,Meow,Scratch | | Dog | Bark,Fetch,Fluffy,Wag | +---------+------------------------------------------------+
Omezení délky
GROUP_CONCAT()
výstup je zkrácen na maximální délku, která je dána parametrem group_concat_max_len
systémová proměnná, která má výchozí hodnotu 1024
. Hodnotu lze nastavit vyšší, ačkoli efektivní maximální délka vrácené hodnoty je omezena hodnotou max_allowed_packet
.
Aktuální hodnotu můžete zkontrolovat takto:
SHOW VARIABLES LIKE '%group_concat%';
Syntaxe pro změnu této hodnoty je následující:
SET [GLOBAL | SESSION] group_concat_max_len = val;
Kde val
je celé číslo bez znaménka.