Столкнулся как-то с задачей вывести из БД MySQL, из одинаковых записей по названию, разные значения в одной строке. Если использовать Group By, то запись будет одна, а вот GROUP_CONCAT позволит совершить операцию конкатенацию (или сложение) данных по заданному полю, через любой разделитель. Самый простой пример - вывести все часы сеансов фильма, несмотря на залы, в которых они показываются. Но как-то столкнулся с задачей, которую сам себе и поставил, более сложную и открыл для себя несколько дополнительных возможностей GROUP_CONCAT.
Итак, у меня есть календарь различных футбольных матчей разных стран и лиг. Я хочу получить таблицу, когда, а точнее в какие дни проходит тот или иной тур какой-либо лиги, причем будущие матчи. Т.е. чтобы я мог посмотреть, что 01,02, ноября будет 19 тур Английского чемпионшипа. Как только я не варьировал различные группировки по лигам, датам и странам - все получалось как зря: или вразброс даты, или дубликат данных, или группировка по матчам, но не по турам, или наоборот. Пока, как водится в период полного отчаяния, не залез в документацию и не узнал, что GROUP_CONCAT может принимать и сортировку и самое важное - вывод только уникальных значений DISTINCT, что исключает повтор даты. А это важно, т.к. по умолчанию есть ограничение по количеству символов. Итого запрос выглядит так:
SELECT strana, liga, tur, GROUP_CONCAT(DISTINCT DATE_FORMAT(data_matcha,"%d.%b") ORDER BY data_matcha SEPARATOR " / " ) as data FROM Table AS Calend WHERE data >= CURDATE() GROUP BY tur, strana, liga ORDER BY data ASC, strana ASC, liga ASC
И также можно использовать условия в запросе
GROUP_CONCAT(DISTINCT поле, CASE WHEN (условие) THEN "" ELSE " (результат)" END ORDER BY поле ASC SEPARATOR ", ")
Т.е. я делаю выборку страны, лиги и тура (поля переименованы для наглядности), а также складываю уникальные значения даты с сортировкой по дате с разделением запятой из таблицы (везде псевдонимы тоже упрощены), при этом сразу привожу дату к читабельному виду (кстати надо не забыть при этом научить таблицу работать с языком страны, я это делал предзапросом SET lc_time_names = "ru_RU"; но будьте аккуратны) где берем дату больше или равной сегодняшнему дню, при этом группируем всю таблицу по туру, стране и лиге, сортируя вначале по датам, а потом по алфавиту.
Возможно, громоздно, возможно неправильно, но я свою задачу решил так. Результат работы можно посмотреть здесь https://sfootball.ru/index/kalendar-budushchih-turov.html
Таким образом я узнал, что можно минуя php сформировать и дату, и получить уникальные данные, чтобы влезть в лимит, без подзапросов и объединения таблиц.
Просто заметка на полях. Не берите как инструкцию, за последствия не отвечаю.