Как заменить дубликат в SQL запросе
Есть 4 таблицы.
Author - Здесь имена исполнителей
| id | name |
-------------
| 1 | Fedor|
-------------
| 2 | Alex |
Track - Здесь название треков
| id | name |
-------------
| 1 | ляля |
-------------
| 2 | олол |
Track_cover - Здесь название картинки трека
| id | id_track | name |
--------------------------
| 1 | 1 |ляля.jpg|
--------------------------
| 2 | 2 |олол.jpg|
Composition - А здесь все вместе собрано
| id | id_track | id_author |
-----------------------------
| 1 | 1 | 1 |
-----------------------------
| 2 | 2 | 1 |
-----------------------------
| 3 | 2 | 2 |
Но есть небольшая проблемка. Есть треки, где авторов два и более, в примере выше я описал это, когда у трека №2 "олол" два автора, Fedor и Alex.
SQL запрос будет выдавать следующее
| track_name | track_author | track_url |
-----------------------------------------
| ляля | Fedor | ляля.jpg |
-----------------------------------------
| олол | Fedor | олол.jpg |
-----------------------------------------
| олол | Alex | олол.jpg |
SELECT track.name as track_name, author.name as track_author, track_cover.name as track_url FROM composition INNER JOIN track ON composition.id_track = track.id INNER JOIN author ON composition.id_author = author.id INNER JOIN track_cover ON track.id = track_cover.id_track
Как лучше поступить в этом случае? Как сделать так, что бы был следующий результат:
- Fedor - ляля
- Fedor & Alex - олол
Какими средствами, лучше добиться данного результата? SQL, PHP, JS? Правильно ли я разбил данные на 4 таблицы, или надо было меньше?
Ответы (2 шт):
GROUP_CONCAT в помощь:
SELECT track.name AS track_name
, GROUP_CONCAT(author.name ORDER BY author.name ASC SEPARATOR ' & ') AS track_author
, track_cover.name AS track_url
FROM composition
INNER JOIN track ON composition.id_track = track.id
INNER JOIN author ON composition.id_author = author.id
INNER JOIN track_cover ON track.id = track_cover.id_track
GROUP BY track.id
Я полагаю что, правильно разбито на 4 таблицы.
Существует функция GROUP_CONCAT которая способна конкатенировать агрегированные результаты колонки. В вашем случае будет нечто такое:
SELECT ... GROUP_CONCAT(author.name) ... FROM ... GROUP BY track.id
Но, имейте в виду, у этой функции есть ограничение на объем выводимых данных. По умолчанию 1024 символа для каждого объединения - для каждой выводимой строки. Но это может быть настроено иначе на разных серверах.
Если нужен более стабильный результат, то придется делать 2 запроса и объединять все вручную.