Доброго времени суток, уважаемые форумчане! Столкнулся, казалось бы, с простецкой задачей, но втупил и не могу понять как составить правильно запрос. Прошу помощи. Описание проблемы: есть 4 таблицы, между которыми есть связь через таблицу product_to_options: products : Код (Text): CREATE TABLE `products` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(250) CHARACTER SET utf8 NOT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_bin product_to_options: Код (Text): CREATE TABLE `product_to_options` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `product_id` INT(10) UNSIGNED NOT NULL, `option_value_id` INT(10) UNSIGNED NOT NULL, `option_field_id` INT(10) UNSIGNED NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `product_id_2` (`product_id`,`option_value_id`), KEY `product_id` (`product_id`) ) ENGINE=INNODB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_bin options_value Код (Text): CREATE TABLE `options_value` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(30) COLLATE utf8_bin NOT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin options_fields Код (Text): CREATE TABLE `options_fields` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(30) COLLATE utf8_bin NOT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin В таблице product_to_options хранится связь товара к ид опции товара и к ид значения опции товара. Например: Код (Text): id | product_id | option_value_id | option_value_field_id 1 1 10 12 2 1 5 9 ... Нужно выбрать все товары и опции к ним с параметрами, но при этом данные должны быть выведенны в таком виде: product_name | options_fields_name_1 | options_value_1 | options_fields_name_2 | options_value_2 | Пробую делать вот такой запрос: Код (Text): SELECT products.id, products.name, options_value.name, options_value.name FROM products JOIN product_to_options ON product_to_options.product_id = products.id JOIN options_value ON product_to_options.option_value_id = options_value.id JOIN options_fields ON product_to_options.option_field_id = options_fields.id ; Получаю закономерный результат вида: Код (Text): id | name | name | name 1 Товар 1 Цвет красный 1 Товар 1 Вес 100кг 2 Товар 2 Цвет синий 2 Товар 2 Вес 10кг .... Вопрос: как мне составить запрос, чтобы убрать дубли для товаров и для дублей вывести значение для опций в каждом столбце? И возможно ли это? Понятно что дубли можно убрать при помощи GROUP BY но вот как быть с выводом значения опций в столбцах а не в строках - не понтно то есть должно быть так: Код (Text): id | name | op_name1 | opt_val_1 | op_name2 | opt_val_2 1 Товар 1 Цвет красный Вес 100кг 2 Товар 2 Цвет синий Вес 10кг ... Используется MySQL 5.7
Разбейте задачу на части - объедините только две таблицы, удостоверившись в желаемом результате. Можно создать из него представление. И так со всеми по очереди. Потом объедините представления.
так убрать или что-то делать? если между таблицами отношение один ко многим или многие ко многим, то "дубли" это естественная картина. принудительно делать их недублями значит что-то сломать. в таких случаях надо сначала решить для себя что конкретно ты хочешь получить: первую запись из возможных, сумму по столцу и т.д --- Добавлено --- иногда "дубли" надо оставить как есть, а обрабатывать их уже в Представлении, например показывать иерархию. или превращать столбцы в колонки реляционные СУБД не приспособлены для вывода записей "по горизонтали" только для фиксированного набора колонок можно сочинить хитрый запрос с несколькими джойнами к той же таблице и доп. условиями Код (Text): SELECT master.id, master.title, MIN(details1.amount) AS color, MIN(details2.amount) AS weight FROM master LEFT JOIN details AS details1 ON details1.master_id = master.id AND details1.type='color' LEFT JOIN details AS details2 ON details2.master_id = master.id AND details2.type='weight' GROUP BY master.id
Сделать, как поступают фреймворки - отдельно запросить товары, отдельно для них опции, потом распределить на стороне PHP