|
|
|
| Привет всем! Помогите составить запрос на выборку, у самого не получается.
Пишу каталог на ПХП. Структура такова:
categories:
+----+------------+
| id | name |
+----+------------+
| 14 | процессоры |
| 15 | видеокарты |
+----+------------+
fields:
+----+--------+-----------+
| id | cat_id | name |
+----+--------+-----------+
| 1 | 14 | модель |
| 2 | 14 | частота |
| 3 | 15 | модель |
| 4 | 15 | слот |
| 22 | 15,14 | цена |
| 23 | 15,14 | на складе |
+----+--------+-----------+
products:
+----+--------+----------+
| id | cat_id | title |
+----+--------+----------+
| 1 | 14 | core2duo |
| 2 | 15 | geforce |
| 3 | 15 | zyxel |
+----+--------+----------+
field_values:
+----+------------+----------+---------+
| id | product_id | field_id | value |
+----+------------+----------+---------+
| 1 | 1 | 1 | 6400 |
| 2 | 1 | 2 | 2000mhz |
| 3 | 2 | 3 | 8800gtx |
| 4 | 2 | 22 | 350 |
| 5 | 1 | 22 | 550 |
| 6 | 3 | 22 | 50 |
| 7 | 3 | 3 | P-660RU |
| 8 | 1 | 23 | Есть |
| 9 | 2 | 23 | Нету |
| 10 | 3 | 23 | Есть |
+----+------------+----------+---------+
|
Как сделать фильтр по дополнительным полям?
Например мне нужно выбрать все product_id из таблицы field_values
где "цена" от 300 до 550
(field_id=22 AND value BETWEEN 300 AND 550)
и поле "на складе" - есть.
(field_id = 23 AND value = 'Есть' )
(таких полей при выборке может быть сколько угодно)
по идеи он должен выбрать product_id - 1 и 3.
Как составить такой запрос?
Прошу очень, помогите если кто знает или может какая идея есть. Очень надо. У самого не получается. Не пойму как сделать =( | |
|
|
|
|
|
|
|
для: Ringo
(05.08.2009 в 18:17)
| | 1 выберет 3 не выберет потомучто у 3 цена 50
или так
SELECT a.product_id FROM
field_values a LEFT JOIN field_values b
ON a.product_id = b.product_id
WHERE (a.field_id=22 AND a.value BETWEEN 50 AND 550)
AND(b.field_id = 23 AND b.value = 'Есть' );
|
но что-то не так с такой структурой | |
|
|
|
|
|
|
|
для: exp
(05.08.2009 в 20:50)
| | Спасибо за ответ.
Я так понял, что если добавится еще одно поле для фильтра. то придется использовать еще один LEFT JOIN? как то так:
SELECT
a.product_id
FROM
field_values a
LEFT JOIN field_values b ON a.product_id = b.product_id
LEFT JOIN field_values c ON a.product_id = c.product_id
WHERE
(a.field_id=22 AND a.value BETWEEN 50 AND 550)
AND (b.field_id = 23 AND b.value = 'Есть' )
AND (c.field_id = 25 AND c.value = 'checked' );
|
а у mysql есть кажись лимит на количества JOINoв?
поэтому много как я понял фильтров использовать не получится. А по другому не получится?
может как то с помощью нескольких запросов..
Ну это единственная структура которую я придумал при создание дополнительных полей. | |
|
|
|
|
|
|
|
для: Ringo
(05.08.2009 в 18:17)
| |
| 22 | 15,14 | цена |
| 23 | 15,14 | на складе |
|
Что это за фигня?
В поле записи никаких списков быть не должно. | |
|
|
|
|
|
|
|
для: Trianon
(05.08.2009 в 22:21)
| | 22 | 15,14 | цена
| 23 | 15,14 | на складе |
15, 14 - я как бы перечислил через запятую id , категорий к которым относится доп поле.
Можно написать и как:
22 | 15 | цена
23 | 14 | цена
24 | 15 | на складе
25 | 14 | на складе
Ну тут особо не важно, тк из пользовательской части передается только field_id
А cat_id в этой таблице нужна только для отображения в админке доступных полей для категории. Я выбираю их с помощью регулярного выражения, если доп поле принадлежит нескольким категориям. это ладно, не столь важно как фильтр по полям. | |
|
|
|
|
|
|
|
для: Ringo
(05.08.2009 в 22:33)
| | >15, 14 - я как бы перечислил через запятую id , категорий к которым относится доп поле.
А я как бы сказал, что так не делают.
А делают так.
из таблицы fields выбрасывают столбик cat_id, поскольку поле (field) не позволяет однозначно определить категорию (cat).
fields:
+----+-----------+
| id | name |
+----+-----------+
| 1 | модель |
| 2 | частота |
| 3 | модель |
| 4 | слот |
| 22 | цена |
| 23 | на складе |
+----+-----------+
|
и добавляют еще одну таблицу соответствия категорий полям:
field_cat_link:
+----------+--------+
| field_id | cat_id |
+----------+--------+
| 1 | 14 |
| 2 | 14 |
| 3 | 15 |
| 4 | 15 |
| 22 | 14 |
| 22 | 15 |
| 23 | 14 |
| 23 | 15 |
+----------+--------+
|
Это классическое отношение многие-ко-многим (N:N)
По большому счету оно в этом плане мало чем отличается от отношения, заданного таблицей field_values, в которой значения полей множественно соответствуют товарам. | |
|
|
|
|
|
|
|
для: Trianon
(05.08.2009 в 22:41)
| | Можно сделать.
Но как это поможет сделать фильтр по дополнительным полям? | |
|
|
|
|
|
|
|
для: Ringo
(05.08.2009 в 22:54)
| | Так а в чем проблема?
Вы переживали насчет ограничения на число JOINов?
Начиная с версии 4.1: D.7.1. Limits of Joins
The maximum number of tables that can be referenced in a single join is 61. This also applies to the number of tables that can be referenced in the definition of a view.
| |
|
|
|
|
|
|
|
для: Ringo
(05.08.2009 в 18:17)
| | Всем большое спасибо за ответы!
Мне на форуме sql.ru подсказали отличное решение )
select product_id from fields
where
(field_id=22 AND value BETWEEN 300 AND 550)
OR
(field_id = 23 AND value = 'Есть' )
group by product_id
having count(1) = 2
|
| |
|
|
|
|
|
|
|
для: Ringo
(06.08.2009 в 17:39)
| | оспидя, какой феерический костыль. | |
|
|
|