问题
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