Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Вывод связанных записей при связи many to many
 
 автор: Temnovit   (08.02.2010 в 11:25)   письмо автору
 
 

Помогите, пожалуйста, может у кого-то был опыт в решении такой задачи.

Есть таблица с товарами и таблица с категориями товаров, связанная связью много-ко-многим (many-to-many) через дополнительную таблицу. То есть в каждой категории может быть несколько товаров и у каждого товара может быть несколько категорий.

goods
id | name | price

categories
id | name

goods_to_categories
good_id | category_id

Задача: вывести список товаров, показав для каждого товара, в каких категориях он находится, перечислив их через запятую.

Как это сделать одним запросом, я так и не придумал. Смог только одним запросом получить список товаров (SELECT * FROM `goods`) и потом пройти по этому списку в РНР и выполнить дополнительный запрос к базе для каждой записи, чтобы получить категории в которой эта запись находится.

Нечего и говорить, что нагрузка на сервер от такого скрипта катастрофическая - 100 записей на страницу, это 101 запрос к базе. Как можно решить такую задачу более элегантно?

  Ответить  
 
 автор: Temnovit   (08.02.2010 в 12:01)   письмо автору
 
   для: Temnovit   (08.02.2010 в 11:25)
 

Задачу удалось решить, прошу прощения за беспокойство :)

Надеюсь кому-то поможет найденный мной ответ. Помогла функция GROUP_CONCAT, которая собирает значения, возвращая их список через запятую в виде строки.

Вот такой запрос:

SELECT
    `goods`.* ,
    GROUP_CONCAT( `categories`.`name` )  AS `categories`
FROM
    `goods`,
    `categories`,
    `goods_to_categories`
WHERE
    `goods`.`id` = `goods_to_categories`.`good_id`  AND
    `categories.`id` = `goods_to_categories`.`category_id`
GROUP BY `goods`.`id` 

  Ответить  
 
 автор: Trianon   (08.02.2010 в 12:53)   письмо автору
 
   для: Temnovit   (08.02.2010 в 12:01)
 

Вот так будет покрасивше.
SELECT
    `goods`.* ,
    GROUP_CONCAT( `categories`.`name` )  AS `categories`
  FROM
    `goods` 
      LEFT JOIN `goods_to_categories` ON  `goods_to_categories`.`good_id` = `goods`.`id` 
      LEFT JOIN `categories` ON `categories.`id` = `goods_to_categories`.`category_id`
  GROUP BY `goods`.`id`  

А вот так - вообще идеально.
SELECT
    `goods`.* , `cats` 
  FROM
    `goods` 
    LEFT JOIN 
      (
      SELECT 
          `good_id`, GROUP_CONCAT( `categories`.`name` )  AS `cats` 
        FROM 
          `goods_to_categories` 
            JOIN `categories` ON `categories.`id` = `goods_to_categories`.`category_id`
        GROUP BY `good_id`  
      )AS good_cats
            ON  `good_cats`.`good_id` = `goods`.`id` 

  Ответить  
 
 автор: Temnovit   (08.02.2010 в 16:38)   письмо автору
 
   для: Trianon   (08.02.2010 в 12:53)
 

Спасибо, в этих запросах предусмотрен вариант, когда товар не включен ни в одну категорию.

  Ответить  
 
 автор: Temnovit   (09.02.2010 в 16:52)   письмо автору
 
   для: Trianon   (08.02.2010 в 12:53)
 

Кстати, на какие колонки стоит расставить индексы, чтобы запрос выполнялся быстро, учитывая что в каждой из таблиц 10-100 тысяч записей? Достаточно ли первичных ключей?

  Ответить  
 
 автор: Trianon   (09.02.2010 в 17:13)   письмо автору
 
   для: Temnovit   (09.02.2010 в 16:52)
 

на чужие ключи.
В таблице-связке - два составных ключа можно попробовать поставить.
gc(good_id , category_id)
cg(category_id, good_id)
Еще на поля ORDER BY (если требуется)

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования