http://webi.ru/webi_articles/8_14_f.html

GROUP_CONCAT( ) в Mysql.
Сегодня хочу рассказать об интересной функции в Mysql.
Как оказалось, знают ее очень не многие программисты, уж не знаю почему ей мало кто пользуется, но я опросил десятка два своих знакомых и меньше половины знали о GROUP_CONCAT.
Эта функция работает примерно как CONCAT_WS(Объединяет строки с разделителем), только в отличии от CONCAT_WS способна объеденить результаты выборки из таблицы.

Синтаксис
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr}
[ASC | DESC] [,col_name ...]]
[SEPARATOR str_val])

Приведу обычный пример с домашними животными
Например есть таблица, в которой каждому человеку присваивется жвивотное, которое у него есть.

CREATE TABLE `test` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(250) NOT NULL, # это имя человека
`pet` varchar(250) NOT NULL, # это домашнее животное
PRIMARY KEY (`id`)
);

Данные в табличке вот такие
маша - попугай
света - кошка
маша - хомяк
юля - собака
света - собака
маша - рыбки

Из этой таблички видно, что
у Маши есть попугай, хомяк и рыбки,
у Светы кошка и собака,
а у Юли только собака.
Так вот есть задача вывести всех людей из таблицы и чтобы возле каждого показывалось, какие животные у него есть.

Делаем вот такой запрос
SELECT `name`, GROUP_CONCAT(`pet`) as `pet`
FROM `test`
GROUP BY `name`

Результат получается такой
маша - попугай,хомяк,рыбки
света- кошка,собака
юля - собака

Получилось объединение всех животных каждого человека.
GROUP BY `name` в конце сгруппировывает одинаковые имена, можно сказать отбрасывает дубли.

Пример конечно не очень жизненый, не часто встречаются такие избыточные данные, обычно имена хранят в одной таблице, животных во второй, а связи в третьей таблице.
Вот как раз для такого случая и будет полезна GROUP_CONCAT( ).
Приведу пример с вложенным запросом.

SELECT DISTINCT `name` as `name1`,
(select GROUP_CONCAT(`pet`) as `pet` from `test` where `name` = `name1` )as `pet`
FROM `test`

Этот пример использует вложенный select для создания поля со списком животных...
DISTINCT отбрасывает одинаковые имена. Поле name переименовываем, чтобы можно было во вложенном запросе правильно обратиться.
Этот пример уже более похож на пример из жизни.
Выводятся имена, отбрасывая одинаковые, выдергивается список животных для каждого имени.
Все очень просто. Не нужно получать каждое имя, а затем выдергивать животных для каждого имени, все происходит одним запросом.

А теперь подробнее про эту хитрую GROUP_CONCAT.

Разделитель.
По умолчанию используется разделитель запятая.
Если есть необходимость, можно задать другой разделитель

SELECT DISTINCT `name` as `name1`,
(select GROUP_CONCAT(`pet` SEPARATOR '::') as `pet` from `test` where `name` = `name1` )as `pet`
FROM `test`

Сейчас животные будут разделены не запятой, а двойным двоеточием (::)

А остальные возможности этой функции понятны из описаного синтаксиса (сортировка и исключение одинаковых записей).

Несколько разочарований.

Ограничение 1024.
У этой функции есть ограничение на объем выводимых данных.
По умолчанию 1024 символа для каждого объединения - для каждой выводимой строки.
Если размер склееных данных больше, то он будет урезаться.
Чтобы расширить размер нужно выполнить команду SET group_concat_max_len =4096;
Если у вас есть привелегии, то вы расширите объем получаемых данных до 4096, можно и больше.
Но чаще всего на обычных хостингах таких привелегий нет.

Только текст.
Следущая особенность GROUP_CONCAT это работа только со строками.
Если вы захотите склеить числа, то у вас ничего не получится, нужно преобразовать число в текст.

Допустим вы хотите получить не животных, а список ID.
Обычный вариант работать не будет, нужно конвертировать число в текст, например вот так

SELECT DISTINCT `name` as `name1`,
(select CONVERT(GROUP_CONCAT(`id`) USING cp1251) from `test` where `name` = `name1` )as `pet_id`
FROM `test`

 

 

Как работает вар дамп var_damp($a,$b,'gg');

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

   
© 2012 Программирование в удовольствие Яндекс.Метрика Suffusion theme by Sayontan Sinha