Как выполнить фильтрацию характеристик товаров с учетом их количественного значения?

Слева запрос отображает все доступные фасеты (опции) товаров, в то время как справа представлены только те фасеты, которые соответствуют установленным условиям фильтрации. <b>Как можно изменить запрос справа, чтобы он также включал фасеты, не удовлетворяющие условиям фильтрации, но имел нулевые значения для них?</b> <br/> <br/>
  • 20 ноября 2024 г. 7:03
Ответы на вопрос 2
Чтобы изменить запрос таким образом, чтобы он включал фасеты, не удовлетворяющие условиям фильтрации, но имел нулевые значения для них, вы можете воспользоваться следующим подходом:

1. **Основной фильтр**: Сохраните существующий фильтр, который отображает только те фасеты, которые удовлетворяют установленным условиям.

2. **Объединение с полным списком фасетов**: После применения фильтра можно выполнить объединение с полной коллекцией доступных фасетов. Это позволит вам получить все возможные фасеты, даже те, которые не удовлетворяют условиям фильтрации.

3. **Условие на количество**: Для фасетов, которые не удовлетворяют условиям фильтрации, нужно задать значение 0. Для этого вы можете использовать конструкцию, которая возвращает 0 для таких фасетов.

Примерно это можно реализовать на SQL (или в другом языке запросов):

```sql
SELECT
  f.facets,
  COALESCE(f.count, 0) AS count
FROM
  full_facets_list f
LEFT JOIN
  (SELECT facet, COUNT(*) AS count
   FROM products
   WHERE <условия фильтрации>
   GROUP BY facet) filtered_facets
ON f.facets = filtered_facets.facet
```

### Пояснения:
- **full_facets_list** - это полный список возможных фасетов.
- **products** - это таблица с товарами, по которой вы хотите фильтровать.
- **COALESCE** - функция, которая возвращает первый ненулевой аргумент, таким образом, если фасет не удовлетворяет условиям, будет возвращено 0.

Этот подход гарантирует, что все доступные фасеты будут показаны в результатах, независимо от того, есть ли у них товары, соответствующие условиям фильтрации.
Из where убрать дополнительное условие фильтрации, и добавить его же в case в count. 
Тогда count будет отбивать именно статистику по условиям фильтрации (считается все, что выходит из case не null), но занулять там, где условия не выполняются.
...
count(
case
when p.id = ANY (
	SELECT prod_id
	FROM "Product_properties" pp
	WHERE pp.attr_alias = 'ram' AND pp.option_alias IN ('2gb','3gb','4gb','8gb')
)
AND
p.id = ANY (
    SELECT prod_id
    FROM "Product_properties" pp
    WHERE pp.attr_alias = 'storage' AND pp.option_alias IN ('16gb','128gb')
)    
then 1
end
)
...

PS: Подзапросы Any можно вынести в секцию With, если они дают однотипную выборку и используются во многих местах.
Похожие вопросы