SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 27.04.2009 02:12:06

saigo
Участник
Зарегистрирован: 26.04.2009
Сообщений: 3

Запрос в запросе

Такая проблема:
Таблицы:
CREATE TABLE products (
  products_id int NOT NULL auto_increment,
...
  products_image varchar(64),
  products_price decimal(15,4) NOT NULL,
  PRIMARY KEY (products_id),
  KEY idx_products_date_added (products_date_added)
);

CREATE TABLE products_description (
  products_id int NOT NULL auto_increment,
  language_id int NOT NULL default '1',
  products_name varchar(64) NOT NULL default '',
...
  PRIMARY KEY  (products_id,language_id),
  KEY products_name (products_name)
);

CREATE TABLE products_to_categories (
  products_id int NOT NULL,
  categories_id int NOT NULL,
  PRIMARY KEY (products_id,categories_id)
);

CREATE TABLE categories (
  categories_id int NOT NULL auto_increment,
  parent_id int DEFAULT '0' NOT NULL,
...
  PRIMARY KEY (categories_id),
  KEY idx_categories_parent_id (parent_id)
);

CREATE TABLE categories_description (
  categories_id int DEFAULT '0' NOT NULL,
  language_id int DEFAULT '1' NOT NULL,
  categories_name varchar(32) NOT NULL,
...
  PRIMARY KEY (categories_id, language_id),
  KEY idx_categories_name (categories_name)
);

Необходимо сделать выборку из этих таблиц для каждого продукта. С этим проблем нету:


<?php
$lnk = mysql_connect('localhost', 'root', 'xxxx')
       or die ('Not connected : ' . mysql_error());
mysql_select_db("shop");

   
$select="select products_description.products_name, products_description.products_id, products_description.language_id, products.products_price, products.products_image, products.products_id, products_to_categories.products_id, products_to_categories.categories_id, categories_description.categories_name
from products_description, products, products_to_categories, categories_description
where products_description.language_id ='2'
AND products_description.products_id = products.products_id
AND products_to_categories.products_id = products.products_id
AND products_to_categories.categories_id > 0
AND categories_description.categories_id = products_to_categories.categories_id
AND categories_description.language_id='2'
"
;
$sql_result=mysql_query($select);
$rows=mysql_num_rows($sql_result);

for ($n=0; $n<$rows; $n++){

    $row=mysql_fetch_object($sql_result);
    echo $row->products_name . " || " .
    $row->products_price . " || " .
    $row->products_id . " || " .
        $row->products_image ." || " .
    $row->categories_name . "\n";
}
?>
 


Получаем, то что надо:
Отражение || 615.00 || 12 || 12_0.jpg || Пейзаж
...

Проблема в том, что категории могут быть вложенными –
Отражение || 615.00 || 12 || 12_0.jpg || Жывопись > Пейзаж

Как это решить?

Неактивен

 

#2 27.04.2009 03:13:43

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Запрос в запросе

1. Слово «живопись» пишется через «и» smile
2. Одним запросом не отделаетесь, прийдется писать хранимую процедуру или серию
запросов по получению родителей.

Как вариант — сделать денормализованную табличку «все родители», тогда можно будет
объединить с ней, и обойтись одним запросом. В этом случае дополнительные запросы
просто переезжают на этап поддержания этой таблички.

Пусть, например, есть категории
живопись = 1
пейзаж = 2 (родитель = 1)
пейзаж с домиком = 3 (родитель = 2)
Тогда табличка «все родители» должна быть вида
id | parent
------------
2 | 1
3 | 2
3 | 1

Неактивен

 

#3 27.04.2009 11:28:41

saigo
Участник
Зарегистрирован: 26.04.2009
Сообщений: 3

Re: Запрос в запросе

paulus написал:

1. Слово «живопись» пишется через «и» smile
2. Одним запросом не отделаетесь, прийдется писать хранимую процедуру или серию
запросов по получению родителей.

Как вариант — сделать денормализованную табличку «все родители», тогда можно будет
объединить с ней, и обойтись одним запросом. В этом случае дополнительные запросы
просто переезжают на этап поддержания этой таблички.

Пусть, например, есть категории
живопись = 1
пейзаж = 2 (родитель = 1)
пейзаж с домиком = 3 (родитель = 2)
Тогда табличка «все родители» должна быть вида
id | parent
------------
2 | 1
3 | 2
3 | 1

Так оно и есть в таблице categories:

categories_id  |  parent_id
------------
1 | 0
2 | 1
3 | 2

Только в таком виде...

Неактивен

 

#4 27.04.2009 15:14:42

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Запрос в запросе

Нет, оно не в таком виде, как надо. Надо именно «все родители» (включая бабушек, прабабушек и т.д.)
Или несколько запросов (рекурсивно).

Неактивен

 

#5 27.04.2009 17:16:52

saigo
Участник
Зарегистрирован: 26.04.2009
Сообщений: 3

Re: Запрос в запросе

Ну оно такое какое есть, там всего 2 уровня (parent_id=0 – это первый уроверь (родитель), parent_id=1... – это второй уровень) вот кусок дампа:

INSERT INTO `categories` (`categories_id`, `categories_image`, `parent_id`, `categories_status`, `categories_template`, `group_permission_0`, `group_permission_1`, `group_permission_2`, `group_permission_3`, `listing_template`, `sort_order`, `products_sorting`, `products_sorting2`, `date_added`, `last_modified`) VALUES
(10, '', 0, 1, 'default', 0, 0, 0, 0, 'default', 3, 'p.products_price', 'ASC', '2007-12-06 21:02:48', '2008-02-19 19:57:34'),
(13, NULL, 8, 1, 'default', 0, 0, 0, 0, 'default', 0, 'p.products_price', 'ASC', '2008-01-30 15:35:11', NULL),
(12, '', 11, 1, 'default', 0, 0, 0, 0, 'default', 0, 'p.products_price', 'ASC', '2007-12-08 17:42:16', '2008-03-27 11:48:58'),
(11, '', 0, 1, 'default', 0, 0, 0, 0, 'default', 1, 'p.products_price', 'ASC', '2007-12-07 18:26:41', '2008-02-19 19:55:55'),
(8, '', 0, 1, 'default', 0, 0, 0, 0, 'default', 6, 'p.products_price', 'ASC', '2007-12-06 20:01:52', '2008-02-19 19:58:56'),
(7, '', 0, 1, 'default', 0, 0, 0, 0, 'default', 2, 'p.products_price', 'ASC', '2007-12-06 19:57:40', '2008-02-19 19:57:15'),
(9, '', 0, 1, 'default', 0, 0, 0, 0, 'default', 8, 'p.products_price', 'ASC', '2007-12-06 20:27:29', '2008-02-19 19:59:38'),
(15, NULL, 8, 1, 'default', 0, 0, 0, 0, 'default', 0, 'p.products_price', 'ASC', '2008-01-30 16:29:17', NULL),
(14, NULL, 8, 1, 'default', 0, 0, 0, 0, 'default', 0, 'p.products_price', 'ASC', '2008-01-30 16:26:17', NULL),
(16, NULL, 8, 1, 'default', 0, 0, 0, 0, 'default', 0, 'p.products_price', 'ASC', '2008-01-30 16:31:18', NULL),
(17, NULL, 8, 1, 'default', 0, 0, 0, 0, 'default', 0, 'p.products_price', 'ASC', '2008-02-02 13:38:15', NULL),
(18, NULL, 8, 1, 'default', 0, 0, 0, 0, 'default', 0, 'p.products_price', 'ASC', '2008-02-02 13:55:46', NULL),
(19, NULL, 8, 1, 'default', 0, 0, 0, 0, 'default', 0, 'p.products_price', 'ASC', '2008-02-02 13:56:51', NULL),
(20, NULL, 8, 1, 'default', 0, 0, 0, 0, 'default', 0, 'p.products_price', 'ASC', '2008-02-02 19:17:39', NULL),
(21, NULL, 0, 1, 'default', 0, 0, 0, 0, 'default', 7, 'p.products_price', 'ASC', '2008-02-02 20:28:10', '2008-02-25 12:47:26'),
...;


Поскольку это коробочный продукт, то никто небудет переделывать систему.
Но возникло необходимость вывести инфо о продуктах в таком виде:
название || цена || id || фото || категория (включая родителей)

каждый продукт в своей строке, для передачи другому сервису...

Подскажите, как это сделать (желательно с примером, посколько я в этом вопросе балбес)

Неактивен

 

#6 27.04.2009 18:25:58

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Запрос в запросе

Тогда самое простое — написать кусок на том же PHP, раз уж Вы его используете:


<?php

function parent ($id, $lang)
{
  $r = mysql_query ("SELECT c.parent_id AS p, d.categories_name AS n FROM categories c JOIN categories_description d USING (categories_id) WHERE c.id = $id AND d.language_id = $lang");
  $d = mysql_fetch_assoc ($r);
  if ($d['p'] == 0)
    return $d['n'];
  else
    return $d['n'] . ' :: ' . parent ($d['p'], $lang);
}

?>
 

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson