[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Задача с фильтрами
masterlelik
Не получается решить следующую задачу - создание дерева фильтров.
Такие фильтры есть на сайте http://www.vasko.ru/to_catalog/action_categDesc/id_1193/

Когда выбирается какой-то подпункт в правом столбце, то остаются только те фильтры, для которых есть товары с выбранным фильтром.

Есть три таблицы:
1) t_tovars таблица с товарами, которая имеет поля:
id, title
2) t_filters таблица с фильтрами
id, parent_id, title - у категорий верхнего уровня "Бытовая техника", "Марка", "Мощность" parent_id=0
3) t_filter_values таблица хранящая свойства этих товаров
filter_id, filter_value, tovar_id,
где
filter_id - соответствует t_filters.id,
filter_value соответствует t_filters.id для подкатегорий у которых parent_id>0
tovar_id соответствует t_tovars.id

Когда ни один фильтр не выбран, то количества считать просто, через count и group by.
А вот как определить количества когда выбрано несколько фильтров из РАЗНЫХ групп?


_____________
Игорь_Vasinsky
точно так же
Цитата
считать просто, через count и group by.


_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
masterlelik
Цитата
точно так же

А можно пример?
Вся сложность в том, как учесть разные выбранные фильтры...

_____________
Игорь_Vasinsky
Цитата
А можно пример?
Вся сложность в том, как учесть разные выбранные фильтры...


select count(*) from table where
cell = 2
and cell2 in(1,2,3)
or cell3 like '%123%'
group by cell4


_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
masterlelik
Цитата

select count(*) from table where
cell = 2
and cell2 in(1,2,3)
or cell3 like '%123%'
group by cell4

если я правильно понимаю, то все cell это выбранные фильтры, и тогда так работать не будет из-за особенности таблицы t_filter_values. Допустим есть 3 строки в этой таблице
filter_id | filter_value | tovar_id
1 | 5 | 100
2 | 6 | 100
1 | 5 | 101
Так вот если просто выбранные фильтры просто перечислить через and, то не выберется НИЧЕГО.
Например
filter_value = 5 and filter_value = 6 - не будет ни одной строки, которая бы удовлетворяла этим условиям (в данной структуре таблицы это невозможно).

И структура and cell2 in(1,2,3) также не дает решения.
Например: filter_value in (5, 6) and filter_value in (6, 8, 9)
Тут выберется только, то что имеет свойство filter_value=6, но не найдет товар имеющих два свойства 5 и 6.

И объедение через or в таком виде также не работает, потому что будет возможен вариант 5 или 6. А не четкое 5 и 6.

_____________
GET
Цитата
Например: filter_value in (5, 6) and filter_value in (6, 8, 9)
Тут выберется только, то что имеет свойство filter_value=6, но не найдет товар имеющих два свойства 5 и 6.

И объедение через or в таком виде также не работает, потому что будет 5 или 6. А на четкое 5 и 6.


Вы можете более внятно объяснить, что вы хотите сделать? Конкретный пример.

_____________
Не тот велик, кто не падал, а тот кто падал и поднимался.
sergeiss
Цитата (masterlelik @ 9.10.2014 - 09:24)
Например: filter_value in (5, 6) and filter_value in (6, 8, 9)

А кто ж мешает написать "filter_value in (5,6,8,9)"?

И на самом деле, объясни более четко, что ты хочешь получить. То есть, расскажи именно ЧТО, а не КАК ты это хочешь получить. А уже вместе подумаем, как реализовать.

Цитата (masterlelik @ 8.10.2014 - 21:34)
А вот как определить количества когда выбрано несколько фильтров из РАЗНЫХ групп?

Ну вот, например, тут не понятно. По какой логике объединяются фильтры из разных групп - "и"/"или". То есть, фильтры должны быть все одновременно или "хотя бы один из"?

Заодно замечу, что условия в запросе WHERE можно объединять скобками, строя достаточно сложные конструкции. Например, так:
(...) OR ( (...) AND (....) ) OR ( (...) AND (...) AND (...) ) OR ( (...) OR (...) ) 


_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
masterlelik
Думал, что по ссылке более чем понятно. Вот пример:

Есть три категории с возможными вариантами выбора.
Всего 60 товаров, и каждый товар имеет по одному значению из каждой категории, например {холодильник, siemens, 100Вт}

Ниже дерево фильтров:
1) Техника
- Холодильники (10)
- Стиральные машины (20)
- Микроволновки (30)

2) Марка
- Bosch (15)
- Siemens (25)
- Ardo (20)

3) Мощность
- 100Вт (5)
- 200Вт (10)
- 300Вт (45)

Допустим, выбрали в первой группе фильтров два значения Холодильники и Микроволновки, а во второй Siemens
И необходимо узнать сколько Холодильников и Микроволновок марки Siemens имеют мощности: 100, 200 и 300 Вт.

_____________
kaww
masterlelik, может, конечно, где-то накосячил, но думаю что как-то так:
/* filter logic OR */
select t1.filter_id, count(*)
from t_filter_values as t1
where t1.tovar_id in (
select t0.tovar_id
from t_filter_values as t0
where (t0.filter_id="$id[0]" and t0.filter_value = "$value[0]")
or (t0.filter_id="$id[n]" and t0.filter_value = "$value[n]")
)

group by t1.filter_id;

/* filter logic AND */
select t1.filter_id, count(*)
from t_filter_values as t1
where t1.tovar_id in (
select t01.tovar_id from (
select t0.tovar_id, count(*) as _count
from t_filter_values as t0
where (t0.filter_id="$id[0]" and t0.filter_value = "$value[0]")
or (t0.filter_id="$id[n]" and t0.filter_value = "$value[n]")
group by t0.tovar_id having _count = "n+1"
) as t01
)
group by t1.filter_id;
masterlelik
kaww
в первом варианте - во всех блоках всегда остаются только один вариант, даже если и другие варианты отвечают параметрам. Количества получаются какие-то очень завышенные, в несколько раз больше чем изначальные, когда фильтры не выбраны. И сам запрос выполнялся 14 секунд.

Второй вариант дает аналогичный результат, только время выполнения запроса хорошее, меньше 0.1 секунды.

Именно по второму варианту я тоже думал, но без вложенного запроса, используя having и связки (... and ...) or (... and ...)

_____________
masterlelik
kaww
второй вариант работает, нужно только поменять поле во внешнем group by на
t1.filter_value

спасибо!

_____________
masterlelik
вот еще один работающий вариант, наверное, более простой
SELECT FV.filter_id, FV.filter_value, COUNT(FV.tovar_id) FROM t_filters_variables FV 
WHERE FV.tovar_id IN (
SELECT FV2.tovar_id FROM t_filters_variables FV2 WHERE FV2.filter_value IN (300, 301) GROUP BY FV2.tovar_id HAVING count(FV2.filter_value) >= ".$n."
) GROUP BY FV.filter_value


где $n - количество выбранных фильтров, в данном случае n=2 (300 и 301)

_____________
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.