WeBinstruments

Инструментарий для веб-мастеров

 

на сайте на всех сайтах для веб разработчиков везде
 
 Скрипты
  PHP скрипты   
  Flash скрипты   
  Javascript скрипты   

 Софт
  Инструменты SEO   
  Разработка сайтов   
  Серверное ПО   

 Документация
  MySQL   
  PHP   
  HTML   
  Протоколы и сервисы Internet   

 Статьи
  PHP   
  MySQL   
  Сервер   
  еще...   

 Услуги и сервисы
  Домены   
  Хостинги   
  Блоки для сайта   

 Новости


 Контакты
  icq: 158325531
  email:
  все контакты: здесь




Atom все поступления
Раздел Файлы
Раздел Услуги и сервисы
Раздел Новости
Раздел Статьи
комментарии



 Партнеры


Главная / Статьи / MySQL / GROUP_CONCAT( ) в Mysql.


GROUP_CONCAT( ) в Mysql.

04.10.2008
сайт автора: http://webi.ru
публикация данной статьи разрешена только со ссылкой на сайт автора статьи

Подробное описание функции GROUP_CONCAT( ) в Mysql.

Читать всю статью


Комментарии

RSS комментарии


31.05.2010 Павел фром да Таганрог
Спасибо огромное за сию заметку !
В старой версии одного движка с которым мы работаем был атрибут представляющий строку склееную из нескольких значений другого атрибута..в новой версии его убрали...и функций для работы в старом стиле не оставили...
чуть голову не сломал...



03.08.2010 artoodetoo
Век живи - век учись. Спасибо, штучка может пригодиться!



09.08.2010 STEREOLOVER.CS
Народ бьюсь уже кучу времени. Есть запрос, объединяющий три таблицы. Пусть они будут называться car, box и load. Объёдинены они с использованием left join
см см см м3
car.name box.name box.height box.width box.depth load.name load.volume
жигули ящик 1 20 30 50 корова 0,5
жигули ящик 2 10 50 10 свинья 0,2
ламборгини ящик 3 15 15 20 картошка 0,1
ламборгини ящик 3 15 15 20 марковка 0,15
ламборгини ящик 4 10 10 10 null null



Там где нул как вы догадываетесь ящик без груза. Задача следующая. Нужно вычислить объём всех ящиков и объём всех грузов и группировать это всё по имени машины.

car.name box_volume load_volume
жигули 1,1 0,7
ламборгини 0,7 0,25


P.S. в box_volume не рассчитывал точно, а поставил цифры от балды. Дынные выше только для примера как должно выглядеть в итоге.

Сам запрос выглдядит примерно так:
select car.name

from car, box left join load on box.id=load.box_id
where....
group by car.name

Стал на, том что не могу посчитать объём всех ящиков, т.к. если просто указать SUM(box.height*box.width*box.depth)/1000000 у меня объём ящика 3 посчитается 2 раза, а если использовать вложенный запрос для выбора только подходящих строк из box между select и where, то GROUP BY car.name не группирует данные из подзапроса :( Подскажите как можно решить данную задачу?



10.08.2010 гросс
STEREOLOVER.CS, вот ты задачу загнул.
Даже интересно, сможет тебе кто-то ответить или нет...
Ведь тут только для того, чтобы вникнуть, надо час думать, а после этого еще решить данную задачу.
Я подобные задачи решал иначе,
делал дополнительную таблицу, в которой хранил подсчитанные результаты, в данном случае по каждой машине.
В итоге при выводе информации нагрузка на много меньше, чем создавать такие хитрые запросы как у тебя.



28.09.2010 Александр
Огромное спасибо автору за статью - давно искал такую функцию, уже отчаился найти, приходилось обходить через известное тёмное место :)
СПАСИБО!!!



19.10.2010 Искатель
Хорошая статья, спасибо! Подскажите пожалуйста:

Генерируется следующий запрос:

SELECT * FROM main_tbl WHERE caption LIKE '%слово_1%' OR caption LIKE 'слово_2' OR info LIKE '%слово_1%' OR info LIKE '%слово_2%'

Возможно ли каким-то образом склеить 2 поля в запросе для задания общего условия к ним.

Ну что-то наподобие такого:

SELECT * FROM main_tbl WHERE caption+info LIKE '%слово_1%' OR caption+info LIKE 'слово_2'

???

ps1.. Соответственно знак "+" я указал для понимания ... существует ли какая либо функция, или может быть GROUP_CONCAT() мне поможет, только каким образом это реализовать.

ps2.. На php механизм формирования запроса следующий (во избежании некоторых вопросов):

<?php
$search_words="слово_1 слово_2"; // слов может быть произвольно много, либо 1

$query = "SELECT * FROM main_tbl WHERE caption LIKE '%". str_replace(" ", "%' OR caption LIKE '%", $search_words). "%' OR info LIKE '%". str_replace(" ", "%' OR info LIKE '%", $search_words). "%'";
?>



19.10.2010 админ
Искатель, вариантов решения этого вопроса много, все зависит от объема и типа данных.
Конкретно функция которую вы просите вот:

CONCAT_WS(' ', `поле1`, `поле2 `, `поле3`, ...)
Эта функция склеивает данные. Первый аргумент, это разделитель который добавится между склееными данными, в данном примере пробел.

SELECT * FROM `main_tbl` WHERE CONCAT_WS(' ', `caption`, `info `) LIKE '%слово_1%' OR CONCAT_WS(' ', `caption`, `info `) LIKE 'слово_2'
Только не могу сказать на сколько это будет затратно по ресурсам, наверное склеивать каждый раз большие данные это не выгодно, но смотря какие данные у вас в ячейках, можно использовать полнотекстовый поиск, а можно и создавать временную таблицу и туда погружать данные и потом искать.
Все зависит уже от конкретной ситуации.



19.10.2010 Искатель
Админ, спасибо огромное! По настоящему выручили. Да нет, там размер ячеек 16+64 символа (правда в юникоде, но всё равно не много). Да и количество строк около 300.



10.06.2011 Nachtvolk
Статья аццки нужная, понятно изложена. Для жизненности не хватает только примера с JOIN`ами, придётся самому разгребать.



28.08.2011 dude125
Nachtvolk... вот с JOIN-ами для жизненности))

Стоит задача выбрать все записи из одной таблицы, где поле количество >0, объединив все артикулы из другой таблицы по Id записи в поле Articles, разделяя

значения запятой, а также наименования производителей по артикулу из третьей таблицы, объединив их в поле Mnf также разделяя запятой. Поскольку таких записей

более 100 000, поэтому ограничился 1-й записью для примера.

SELECT
p.`Id`,
GROUP_CONCAT(a.`Article` SEPARATOR ',') as Articles,
GROUP_CONCAT(m.`Name` SEPARATOR ',') as Mnf,
p.nameRu as Title,
p.ItemCount
from
(MnfsArts a inner join Manufacturers m on a.Mnf=m.Id)
inner join Product p on a.Product=p.Id
where
p.ItemCount > 0
and p.Id='10313'
GROUP BY p.Id
ORDER BY m.Name;

Все вроде бы нормально, но длина обединенных строк Articles и Mnf получается 21 байт, а должно быть гораздо больше. Потому как запросом без GROUP BY выводит

все записи с повторяющимся Id соответственно и если подсчитать количество записей, то видно что если объединить поля, длина должна быть больше чем 21 байт.
Немного поразмыслив, решил добавить конверт в строку. Типа:

SELECT
p.Id,
GROUP_CONCAT(CAST(a.Article as CHAR) SEPARATOR ',') as Articles,
GROUP_CONCAT(CAST(m.`Name` as CHAR) SEPARATOR ',') as Mnf,
p.nameRu as Title,
p.ItemCount
from
(MnfsArts a inner join Manufacturers m on a.Mnf=m.Id)
inner join Product p on a.Product=p.Id
where
p.ItemCount > 0
and p.Id='10313'
GROUP BY p.Id
ORDER BY m.Name;


теперь зараза обрубает после 64 символа.

Подскажите кто-нибудь как решить вопрос, может попробовать вместо CAST что-то другое.

Причем на локальной машине тоже самое.
(версия MySQL на локалке - 5.1.54-community, на хостинге - 5.0.26)



28.08.2011 dude125
на кавычки в названиях полей и таблиц не обращайте внимания, в запросе они есть, я просто сюда забыл везде добавить, сорри



28.08.2011 dude125
извините ввел в заблуждение, на локалке все работает нормально, т.е. получается что проблема в версии MySQL?

Тогда вопрос, как увеличить размер строки? или альтернативным запросом в соответствии с версией MySQL?



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

У вас наверное стоит ограничение в 64 байта.



01.09.2011 Миха
Да, вы правы. На хостинге значение этой переменной было вообще 64)). Привилегий на изменение нет. Просил службу поддержки исправить хотя бы до 1024. Сейчас все отлично работает. Спасибо за комментарий.



16.11.2011 Сергей
Только текст.
Следущая особенность GROUP_CONCAT это работа только со строками.

проверил на версиях:
5.0.92
5.1.47
5.5.16
с числами работает так же как и со строками



28.11.2011 Виктор
Сергей, но может зависит от каких-то настроек?
Потому что я сам лично проверял год назад, не работала она напрямую с числами, только после конвертации.



27.08.2012 Сергей
Огромное спасибо автору. Очень полезная статья, как раз то, что я искал.



19.09.2012 alexandr-mov
Дякую, дуже допоміг цей пост



19.03.2014 Александр
Автору респект и уважуха за статю! Недели две бился лбом об монитор, пока не нашел эту статью.



24.12.2014 Евгений
Низкий поклон автору! Наверное, полжизни искал это решение.


1 2 3

Добавить свой комментарий


Ваше имя(* обязательно)


Текст сообщения(* обязательно)









 
 
  запомнить

 
Copyright © 2003-2024 WeBi Constructor
Rambler's Top100