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

Форум MySQL

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

 

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

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

тема: Как правильно сделать выборку
 
 автор: nazgarth   (19.01.2008 в 16:41)   письмо автору
 
 

Пишу доску объявлений на php.
Необходимо чтобы объявления имели разные поля в зависимости от категории (например: видеокарты - модель, слот, частота гп/памяти и т.д., процессоры - модель, частота, кэш и т.д.).
Реализовал следующим образом.
Создал четыре таблицы:
categories - таблица с категориями,
fields - таблица, содержащая названия полей для каждой категории,
products - таблица, в которую добавляется запись со стандартной информацией об объявлении (заголовок, текст, дата и др.),
field_values - таблица, в которую добавляются записи со значениями для динамических полей (fields).

Таблицы (оставлены основые столбцы):


categories:
+----+------------+
| id | name       |
+----+------------+
| 14 | процессоры |
| 15 | видеокарты |
+----+------------+

fields:
+----+--------+---------+
| id | cat_id | name    |
+----+--------+---------+
| 1  | 14     | модель  |
| 2  | 14     | частота |
| 3  | 15     | модель  |
| 4  | 15     | слот    |
+----+--------+---------+

products:
+----+--------+----------+
| id | cat_id | title    |
+----+--------+----------+
| 1  | 14     | core2duo |
| 2  | 15     | geforce  |
+----+--------+----------+

field_values:
+----+------------+----------+---------+
| id | product_id | field_id | value   |
+----+------------+----------+---------+
| 1  | 1          | 1        | 6400    |
| 2  | 1          | 2        | 2000mhz |
| 3  | 2          | 3        | 8800gtx |
+----+------------+----------+---------+


Как правильно сделать выборку в такой структуре? С выводом одного объявления отдельно всё просто. А как, например, выбрать все объявления категории со значениями динамических полей не прибегая к foreach (запросу для каждого объявления)? Реально ли вообще это, или может посоветуете другой способ реализации?

   
 
 автор: Trianon   (19.01.2008 в 22:14)   письмо автору
 
   для: nazgarth   (19.01.2008 в 16:41)
 

SELECT p.id, c.name AS cn,  p.name AS pn, f.name AS fn, fv.value
  FROM products p 
  JOIN categories с ON p.cat_id = c.id AND c.name IN ('процессоры', 'видеокарты')
  LEFT JOIN field_values  fv ON p.id = fv.product_id 
  LEFT JOIN fields f  ON fv.field_id = f.id
ORDER BY c.name, p.name, p.id, f.id, fv.id


Респект. Приятно было ответить.

   
 
 автор: nazgarth   (19.01.2008 в 23:04)   письмо автору
 
   для: Trianon   (19.01.2008 в 22:14)
 

Спасибо.

Т.е. одно объявление будет дублироваться но с разными дин. полями и их значениями? Другого способа нет? А то если таблица разрастётся и при выборке каждое объявление будет умножаться на кол-во полей категории...
Тогда, может, если не сложно, подскажите как более рационально работать с результатом данной выборки:


+----+------------+----------+---------+-------------+
| id | cn         | pn       | fn      | field_value |
+----+------------+----------+---------+-------------+
| 1  | процессоры | core2duo | модель  | 6400        |
| 1  | процессоры | core2duo | частота | 2000mhz     |
| 2  | видеокарты | geforce  | модель  | 8800gtx     |
+----+------------+----------+---------+-------------+


Ещё раз спасибо, заранее.

   
 
 автор: Trianon   (19.01.2008 в 23:36)   письмо автору
 
   для: nazgarth   (19.01.2008 в 23:04)
 

Да как угодно работать.
Например, так:
<?
for($pid ''$row mysql_fetch_row($res);  $pid $id)
{
    list(
$id$cn$pn$fn$fv) = $row;
    
$res $id != $pid "<br /> $cn / $pn :" ",";
    echo 
"$res $fn $fv";
}
?>


Впрочем, если еще чуть поломать мозг, можно написать запрос на уровне MySQL:

SELECT p.id, c.name AS cn,  p.name AS pn, 
    GROUP_CONCAT(f.name,' ', fv.value
        ORDER BY f.id 
        SEPARATOR ', '
    ) AS prop_list
  FROM products p 
  JOIN categories с ON p.cat_id = c.id AND c.name IN ('процессоры', 'видеокарты')
  LEFT JOIN field_values  fv ON p.id = fv.product_id 
  LEFT JOIN fields f  ON fv.field_id = f.id
GROUP BY cn, pn, p.id
ORDER BY cn, pn, p.id

   
 
 автор: nazgarth   (20.01.2008 в 00:30)   письмо автору
 
   для: Trianon   (19.01.2008 в 23:36)
 

Во! Последний запрос - то, что нужно.
Спасибо, что находите время отвечать даже на rtfm'ные вопросы :] На другом форуме врядли бы дождался.

   
Rambler's Top100
вверх

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