Здравствуйте.
Есть фильтр товаров, в котором перечислены все имеющиеся атрибуты товаров (объем памяти, цвет и любые другие свойства).
При выборе атрибутов на странице отображаются отфильтрованные товары. Как можно сделать неактивными (скрыть в фильтре) те атрибуты, по которым уже не осталось товаров после предыдущей фильтрации?
Допустим, в базе есть два товара со следующим набором атрибутов: у одного атрибут оперативка со значением 8 Гб и атрибут цвет со значением красный, у другого оперативка 16 Гб и цвет белый. Изначально в фильтре отображаются все четыре значения атрибута. Мы выбираем атрибут "Оперативка - 8 Гб", и отфильтровывается один соответствующий товар. И нужно как-то скрыть в фильтре ставшие ненужными атрибуты "Оперативка - 16 Гб" и "Цвет - белый", потому что больше не осталось товаров с атрибутом "Оперативка - 8 Гб".
Я пока не понимаю, как это сделать, кроме как делать дополнительный запрос в БД по каждому атрибуту, чтобы узнать, будет возвращен результат или нет, но это очень затратно.
Как это можно сделать нормальным способом?
Примерная структура БД:
Таблица product
Колонки product_id, title
Записи:
1, Xiaomi
2, Samsung
3, Iphone
Таблица attribute
Колонки attribute_id, title
Записи:
1, ram_memory
2, capacity
3, color
4, size
Таблица attribute_values
Колонки product_id, attribute_id, value
Записи:
1, 1, 8Gb
1, 3, red
2, 1, 16Gb
2, 3, white
...
Запрос для вывода атрибутов в фильтре:
SELECT DISTINCT a.attribute_id, a.title, av.value
FROM attribute a
JOIN attribute_values av
WHERE a.attribute_id = av.attribute_id;
Запрос для получения списка товаров после фильтрации:
SELECT p.product_id, p.title
FROM product p
LEFT JOIN attribute_values av ON av.product_id = p.product_id
GROUP BY p.product_id
HAVING (SUM(av.attribute_id = 1 AND av.value = '8Gb') = 1 AND SUM(av.attribute_id = 3 AND av.value = 'red') = 1);
Надеюсь, в запросах не ошибся, т.к. писал упрощенный и схематичный вариант, чтобы передать суть.
Спасибо.