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

Форум MySQL

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

 

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

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

тема: Связь "многие ко многим" и сортировка
 
 автор: Ирбис   (19.03.2011 в 13:46)   письмо автору
 
 

Добрый день!
Возник вот такой вопрос.

Есть 3 таблицы.
1. Таблица с продуктами
CREATE TABLE `products` (
  `id_product` INT(11) NOT NULL AUTO-INCREMENT,
  `name` TEXT NOT NULL DEFAULT '',
  `rating` INT(11) NOT NULL DEFAULT 0,
  PRIMARY KEY (`id_product`)
);


2. Таблица с категориями:
CREATE TABLE `categories` (
  `id_category` INT(11) NOT NULL AUTO-INCREMENT,
  `name` TEXT NOT NULL DEFAULT '',
  PRIMARY KEY (`id_category`)
);


3. Таблица, связывающая продукты с категориями. Один продукт может принадлежать сразу нескольким категориям одновременно.
CREATE TABLE `products_to_categories` (
  `id_product` INT(11) NOT NULL DEFAULT 0,
  `id_category` INT(11) NOT NULL DEFAULT 0
);


Так вот, на странице с категорией нужно вывести все продукты, которые к ней относятся. При этом продукты должны быть отсортированы по рейтингу. Можно, конечно, ввести в третью таблицу столбец `rating` и синхронизировать его со значением в первой таблице. Тогда запрос на выборку продуктов из третьей таблицы будет выглядеть так:
SELECT * FROM `products_to_categories` WHERE `id_category` = 1 ORDER BY `rating`

Но синхронизация полей `rating` в двух таблицах - это дополнительная работа, которую нужно выполнять каждый раз, когда рейтинг будет изменяться.

Можно ли составить такой запрос, чтобы из третьей таблицы выбирались все продукты из выбранной категории и при этом записи сортировались бы по полю `rating`, которое расположено в первой таблице?

  Ответить  
 
 автор: cheops   (19.03.2011 в 13:53)   письмо автору
 
   для: Ирбис   (19.03.2011 в 13:46)
 

Можно отталкиваться от следующего запроса
SELECT
  products_to_categories.id_category AS id_category,
  products_to_categories.id_product AS id_product
FROM 
  products_to_categories
  LEFT JOIN
  products
  ON (
    products_to_categories.id_category = 1 AND
    products_to_categories.id_product = products.id_product
  )
ORDER BY products.rating

  Ответить  
 
 автор: Ирбис   (19.03.2011 в 16:25)   письмо автору
 
   для: cheops   (19.03.2011 в 13:53)
 

Спасибо! Остановился на таком запросе:
SELECT 
  * 
FROM 
  products_to_categories 
  LEFT JOIN 
  products 
  USING (id_product) 
WHERE products_to_categories.id_category = 1
ORDER BY products.rating


После его исполнения в результирующей таблице, как и предполагалось, имеется 4 столбца:
id_product, id_category, name, rating

Но если этот запрос переписать так:
SELECT 
  id_product, id_category
FROM 
  products_to_categories 
  LEFT JOIN 
  products 
  USING (id_product) 
WHERE products_to_categories.id_category = 1
ORDER BY products.rating


или так:
SELECT 
  products_to_categories.id_product,
  products_to_categories.id_category
FROM 
  products_to_categories 
  LEFT JOIN 
  products 
  USING (id_product) 
WHERE products_to_categories.id_category = 1
ORDER BY products.rating

то в результирующей таблице оказывается только 2 столбца: id_product и id_category. Как будто конструкция JOIN ничего не присоединила.
Почему, интересно, так происходит?

  Ответить  
 
 автор: cheops   (19.03.2011 в 16:34)   письмо автору
 
   для: Ирбис   (19.03.2011 в 16:25)
 

Все верно, вы же явно указываете столбцы в операторе SELECT, дело LEFT JOIN дать вам декартовое пересечение таблиц, дело USING, ON и WHERE отобрать строки по условиям, а SELECT выбирать столбцы. Да можно превратить результат многотабличного запроса в результат однотабличного, но обе таблицы будут участвовать в запросе (соответственно, потребляя ресурсы). Попробуйте убрать USING и LEFT - все дублирующие строки сразу выйдут на поверхность.

  Ответить  
 
 автор: Ирбис   (19.03.2011 в 17:12)   письмо автору
 
   для: cheops   (19.03.2011 в 16:34)
 

Спасибо!
Разобрался.

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

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