|
|
|
| Пишу доску объявлений на 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 (запросу для каждого объявления)? Реально ли вообще это, или может посоветуете другой способ реализации? | |
|
|
|
|
|
|
|
для: 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
|
Респект. Приятно было ответить. | |
|
|
|
|
|
|
|
для: Trianon
(19.01.2008 в 22:14)
| | Спасибо.
Т.е. одно объявление будет дублироваться но с разными дин. полями и их значениями? Другого способа нет? А то если таблица разрастётся и при выборке каждое объявление будет умножаться на кол-во полей категории...
Тогда, может, если не сложно, подскажите как более рационально работать с результатом данной выборки:
+----+------------+----------+---------+-------------+
| id | cn | pn | fn | field_value |
+----+------------+----------+---------+-------------+
| 1 | процессоры | core2duo | модель | 6400 |
| 1 | процессоры | core2duo | частота | 2000mhz |
| 2 | видеокарты | geforce | модель | 8800gtx |
+----+------------+----------+---------+-------------+
|
Ещё раз спасибо, заранее. | |
|
|
|
|
|
|
|
для: 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
|
| |
|
|
|
|
|
|
|
для: Trianon
(19.01.2008 в 23:36)
| | Во! Последний запрос - то, что нужно.
Спасибо, что находите время отвечать даже на rtfm'ные вопросы :] На другом форуме врядли бы дождался. | |
|
|
|