MySQL има GROUP_CONCAT()
функция, която ни позволява да връщаме колони от заявка като разделен списък.
Връща резултат от низ с конкатенирания не-NULL
стойности от група.
Синтаксис
Синтаксисът е така:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr}
[ASC | DESC] [,col_name ...]]
[SEPARATOR str_val])
Пример
Да предположим, че изпълняваме следната заявка:
SELECT PetName
FROM Pets;
И получаваме следния резултат:
+---------+ | PetName | +---------+ | Fluffy | | Fetch | | Scratch | | Wag | | Tweet | | Fluffy | | Bark | | Meow | +---------+ 8 rows in set (0.00 sec)
Можем да използваме GROUP_CONCAT()
за да върнете всички тези редове като разделен списък.
За да направим това, трябва да предадем PetName
колона като аргумент на GROUP_CONCAT()
функция:
SELECT GROUP_CONCAT(PetName)
FROM Pets;
Резултат:
+-------------------------------------------------+ | GROUP_CONCAT(PetName) | +-------------------------------------------------+ | Fluffy,Fetch,Scratch,Wag,Tweet,Fluffy,Bark,Meow | +-------------------------------------------------+ 1 row in set (0.01 sec)
Поръчка
Можем да използваме ORDER BY
клауза за подреждане на изхода на тази функция:
SELECT GROUP_CONCAT(PetName ORDER BY PetName ASC)
FROM Pets;
Резултат:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Имайте предвид, че това сортира само изхода на GROUP_CONCAT()
функция – тя е напълно независима от всяка подредба, приложена към SELECT
самото изявление.
DISTINCT
Клауза
Можем да използваме DISTINCT
клауза за връщане на уникални стойности. С други думи, ако има дублиращи се стойности, се връща само едно събитие:
SELECT GROUP_CONCAT(DISTINCT PetName ORDER BY PetName ASC)
FROM Pets;
Резултат:
Bark,Fetch,Fluffy,Meow,Scratch,Tweet,Wag
В този случай Fluffy
се появява само веднъж. Когато го стартираме без DISTINCT
клауза, Fluffy
се появява два пъти.
Промяна на разделителя
По подразбиране списъкът използва запетаята като разделител. Но можем да променим това, ако желаем:
SELECT GROUP_CONCAT(PetName SEPARATOR '-')
FROM Pets;
Резултат:
Fluffy-Fetch-Scratch-Wag-Tweet-Fluffy-Bark-Meow
Можем дори да използваме празен низ, за да премахнем всички разделители (така че стойностите да са свързани):
SELECT GROUP_CONCAT(PetName SEPARATOR '')
FROM Pets;
И получаваме следния резултат:
FluffyFetchScratchWagTweetFluffyBarkMeow
Резултати от групирани заявки
Можем да включим GROUP_CONCAT()
в заявка с GROUP BY
клауза за постигане на резултат като този:
SELECT
PetTypeId,
GROUP_CONCAT(PetName ORDER BY PetName ASC)
FROM Pets
GROUP BY PetTypeId
ORDER BY PetTypeId;
Резултат:
+-----------+--------------------------------------------+ | PetTypeId | GROUP_CONCAT(PetName ORDER BY PetName ASC) | +-----------+--------------------------------------------+ | 1 | Tweet | | 2 | Fluffy,Meow,Scratch | | 3 | Bark,Fetch,Fluffy,Wag | +-----------+--------------------------------------------+
В моята база данни действителните имена на типове домашни любимци са в друга таблица, наречена PetTypes
. Следователно бихме могли да изпълним INNER JOIN
на PetTypes
таблица, за да получите действителните имена на домашни любимци:
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;
Резултат:
+---------+------------------------------------------------+ | PetType | GROUP_CONCAT(p.PetName ORDER BY p.PetName ASC) | +---------+------------------------------------------------+ | Bird | Tweet | | Cat | Fluffy,Meow,Scratch | | Dog | Bark,Fetch,Fluffy,Wag | +---------+------------------------------------------------+
Ограничения на дължината
GROUP_CONCAT()
Изходът на ‘s се съкращава до максималната дължина, която е дадена от group_concat_max_len
системна променлива, която има стойност по подразбиране 1024
. Стойността може да бъде зададена по-висока, въпреки че ефективната максимална дължина на връщаната стойност е ограничена от стойността на max_allowed_packet
.
Можете да проверите текущата стойност по следния начин:
SHOW VARIABLES LIKE '%group_concat%';
Синтаксисът за промяна на тази стойност е както следва:
SET [GLOBAL | SESSION] group_concat_max_len = val;
Където val
е цяло число без знак.