Вывод sql запроса с условием и использованием GROUP_CONCAT

Есть 3 таблицы со связью 1 ко многим.

(Project)-> там находятся все проекты.

CREATE TABLE `project` (
  `id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `description` varchar(255) NOT NULL DEFAULT 'Нет описания',
  `image` text,
  `link` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

(Tags)-> там находятся теги.

CREATE TABLE `tags` (
  `id` int(11) NOT NULL,
  `tag_name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

(P_tags)-> там находятся id проекта и id тега.

CREATE TABLE `p_tags` (
  `project_id` int(11) NOT NULL,
  `tag_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

На данный момент у меня получился такой запрос

SELECT project.id, project.name, project.description, project.image, project.link, GROUP_CONCAT(tags.tag_name) as tags
            FROM project
            LEFT Join p_tags
            ON project.id = p_tags.project_id
            INNER JOIN tags
            ON tags.id = p_tags.tag_id
            WHERE tag_name = '".$tag_filter."'
            GROUP BY project.id

$tag_filter - это название тега.
На данный момент он мне выводит: все значения которые написаны в запросе, но в поле tags выводится только одно название.
Мне нужно чтобы выводилось несколько названий из таблицы
Например:
Сейчас выводится такая конструкция id = 1, name = QuickSettingsTile, description = Simple... tags = java
А мне нужно чтобы выводилось так id = 1, name = QuickSettingsTile, description = Simple... tags = java,kotlin,html


Ответы (2 шт):

Автор решения: Majestio

Примерно вот так:

SELECT 
  project.id,
  project.name, 
  project.description, 
  project.image, 
  project.link,
  GROUP_CONCAT(DISTINCT tags.tag_name ORDER BY tags.tag_name ASC SEPARATOR ', ') AS tags
FROM 
  project
LEFT JOIN 
  p_tags ON project.id = p_tags.project_id
LEFT JOIN 
  tags ON tags.id = p_tags.tag_id
GROUP BY
  project.id, 
  project.name,
  project.description, 
  project.image, 
  project.link
 

Ссылочка для теста

Ну а фильтрацию тегов на допустимость - можно вставить уже потом.

→ Ссылка
Автор решения: Akina

Просто проверяем, что требуемый тег имеется в списке тегов, связанных с проектом:

SELECT p.*, GROUP_CONCAT(DISTINCT tags.tag_name) as tags
FROM project
JOIN p_tags ON project.id = p_tags.project_id
JOIN tags ON tags.id = p_tags.tag_id
GROUP BY p.id
HAVING SUM(tag_name = 'требуемый тег');

Если тег есть среди всех тегов, сравнение для него вернёт 1, сумма будет больше нуля, и запись проекта будет отобрана.

Если тега нет, все сравнения дадут ноль, сумма будет ноль, запись проекта не будет отобрана.

Поскольку нужно наличие определённого тега, достаточно внутреннего связывания (INNER JOIN, ну или просто JOIN), левое связывание не требуется.

Если project.id не определён как первичный ключ (в тексте вопроса - этого нет), то следует в GROUP BY перечислить ВСЕ поля таблицы project, которые будут присутствовать в списке вывода. А по-хорошему, и вместо звезды в списке вывода следует также перечислить все поля.

Если в p_tags имеется естественный первичный ключ, включающий оба поля, то DISTINCT в параметрах GROUP_CONCAT() - лишний и может быть удалён.

→ Ссылка