SQL Query to return filters applicable to products contained in category AND filters that apply from remaining products once 1+ filters active

天涯浪子 提交于 2021-02-11 14:01:01

问题


I'm displaying a list of product filters.
Product filters are only displayed if they are applicable to the products contained within a chosen category.

I want to expand that further so once a filter has been activated, the non-applicable filters are not outputted.

So from the data sample below in products_filters_to_products:

  • Once Orange has been selected as a Colour
  • Only Small from Size should be made available

Query so far returns applicable filter categories, filters belonging to those filter categories and products that they apply to.

Tables and query so far shown below.

Tables

products_filters_to_products
-------------------
pftp_pf_id  pftp_products_id
3           1
4           1
5           2

product_filters
-------------------
pf_id  pf_name  pf_to_pfc_id
1      Red      1
2      Blue     1
3      Orange   1
4      Small    2
5      Medium   2

product_filters_categories
-------------------
pfc_id  pfc_name
1       Colour
2       Size

products_to_categories
-------------------
products_id  categories_id
1            8
2            9

products
-------------------
products_id  products_status
1            1
2            1

Query

SELECT pfc.pfc_id
     , pfc.pfc_name
     , pf.pf_id
     , pf.pf_name
     , COUNT(pftp.pftp_pf_id) products_in_filter 
  FROM products_filters_to_products pftp 
  LEFT 
  JOIN product_filters pf 
    ON pftp.pftp_pf_id = pf.pf_id 
  LEFT 
  JOIN product_filters_categories pfc 
    ON pf.pf_to_pfc_id = pfc_id 
 WHERE pftp_products_id IN ( SELECT ptc.products_id 
                               FROM products_to_categories ptc 
                               LEFT 
                               JOIN products p  
                                 ON ptc.products_id = p.products_id 
                              WHERE p.products_status = 1 
                                AND ptc.categories_id = 2479 ) 
 GROUP 
    BY pfc.pfc_id
     , pftp.pftp_pf_id 
 ORDER 
    BY pfc.pfc_name ASC
     , pf.pf_name ASC

回答1:


You want to show all still matching filter values for filter category 2 (Size), when filter category 1 (Color) already has been set to a value (3 = Orange).

In order to find them, we'd look up all products matching category/value 1(Color)/3(Orange). This is only product 1. And the only filter value for product 1 and filter category 2(Size) is value 4(Small).

Let's make the scenario more complex: Let there be four filter categories: 1, 2, 3, and 4. For filter category 2 the value 22 has been chosen and for filter category 4 the value 44. Now, which values are available for the other filter categories (1 and 3)?

First we must get all item IDs that match both 2/22 and 4/44. This is more complex than just looking up one filter. The typical way of dealing with this is an aggregation:

select pftp.pftp_products_id
from products_filters_to_products pftp
join product_filters pf on pf.pf_id = pftp.pftp_pf_id
group by pftp.pftp_products_id
having sum(pf.pf_id = 22) > 0
   and sum(pf.pf_id = 44) > 0;

(Such queries are very common when dealing with key/value tables as is the case here.) With the product IDs found we look up all their values for the other filter categories:

select pf_to_pfc_id, pf_id, pf_name
from product_filters
where pf_id in
(
  select pftp_pf_id
  from products_filters_to_products
  where pftp_products_id in (<above query>)
)
and pf_to_pfc_id not in 
(
  select pf_to_pfc_id
  from product_filters 
  and pf_id in (22, 44)
)
order by pf_to_pfc_id, pf_id;

If you want only the available filter values for filter category 3, then replace pf_to_pfc_id not in (...) with pf_to_pfc_id = 3.



来源:https://stackoverflow.com/questions/59685243/sql-query-to-return-filters-applicable-to-products-contained-in-category-and-fil

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!