Во-первых, стрелки на диаграмме принято рисовать в другую сторону - это таблица связи ссылается на таблицу продуктов и на таблицу фотографий.
Во-вторых, то чего вы хотите, сделать можно но это неправильный путь. Правильных путей тут два:
- Построить запрос, который выбирает продукты по определенному условию и присоединяет к ним картинки. В этом случае у вас будет несколько записей на один продукт, отличающихся только картинками (это, я так понимаю, вы сумели сделать). Обрабатывать это не очень удобно, но зато один запрос в БД.
- Выбрать сначала продукты, а затем к продуктам выбрать фотографии. Потребуется сопоставить фотографии с продуктами (по ID) на уровне приложения. Зато два запроса в БД и каждый возвращает свой набор требуемых данных.
Третий правильный путь - использовать ORM, которая возьмет на себя извлечение данных из БД.
Неправильный (на мой взгляд) путь - использовать агрегирующие функции, как-то так:
SELECT p.*, JSON_ARRAYAGG(f.filename) AS files FROM product p
LEFT JOIN product2file p2f ON p2f.product_id=p.id
LEFT JOIN file f ON p2f.file_id=f.id
GROUP BY p.id;
Пример
Но я считаю этот путь неправильным, потому что: с ростом сложности БД сложность подобных запросов быстро растет и тут начинают вылазить ошибки. А еще потому что вытащить из подчиненной таблицы 2 колонки можно, но порядок элементов в функции JSON_ARRAYAGG не определен, поэтому начинается возня с тем чтобы все это сопоставить. GROUP_CONCAT тоже имеет проблемы (в первую очередь ограничение длины).
Так что, мне кажется, лучше привыкать к тому что запрос может возвращать несколько строк для одной сущности и учиться с этим работать на уровне приложения, чем извращаться в запросе.