Mysql SQL查询以返回适用于类别中包含的产品的筛选器,以及在1+筛选器处于活动状态时适用于剩余产品的筛选器
我正在显示产品过滤器的列表。 仅当产品过滤器适用于所选类别中包含的产品时,才会显示产品过滤器 我想进一步扩展,一旦一个过滤器被激活,不适用的过滤器就不会输出 因此,从以下产品中的数据样本到产品: 一旦选择橙色作为颜色 应只提供较小的尺寸 迄今为止的查询返回适用的过滤器类别、属于这些过滤器类别的过滤器以及它们应用于的产品 到目前为止的表和查询如下所示 桌子Mysql SQL查询以返回适用于类别中包含的产品的筛选器,以及在1+筛选器处于活动状态时适用于剩余产品的筛选器,mysql,sql,Mysql,Sql,我正在显示产品过滤器的列表。 仅当产品过滤器适用于所选类别中包含的产品时,才会显示产品过滤器 我想进一步扩展,一旦一个过滤器被激活,不适用的过滤器就不会输出 因此,从以下产品中的数据样本到产品: 一旦选择橙色作为颜色 应只提供较小的尺寸 迄今为止的查询返回适用的过滤器类别、属于这些过滤器类别的过滤器以及它们应用于的产品 到目前为止的表和查询如下所示 桌子 products_filters_to_products ------------------- pftp_pf_id pftp_produ
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
质疑
当过滤器类别1颜色已设置为值3=橙色时,您希望显示过滤器类别2大小的所有仍然匹配的过滤器值 为了找到它们,我们将查找所有与类别/值1颜色/3橙色匹配的产品。这只是产品1。产品1和过滤器类别2大小的唯一过滤器值为值4小 让我们将场景变得更复杂:设为四个过滤器类别:1、2、3和4。对于过滤器类别2,选择值22;对于过滤器类别4,选择值44。现在,哪些值可用于其他过滤器类别1和3 首先,我们必须获得与2/22和4/44匹配的所有项目ID。这比只查找一个过滤器更复杂。处理此问题的典型方法是聚合:
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;
这种查询在处理键/值表时非常常见,这里就是这种情况。找到产品ID后,我们将查找其他过滤器类别的所有值:
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;
如果您只需要筛选器类别3的可用筛选器值,请将pf_替换为pfc_id not in。。。当pf_到pfc_id=3时。注意左连接p。。。其中p=。。。与内部联接p相同。请看:另一方面:我认为使用不同的列名会更容易阅读,这些列名在任何表中都保持不变,例如product\u filters product\u filter\u id、name、product\u filter\u category\u id和products\u filters\u to\u products\u filter\u id,product_id。@ThorstenKettner我过去曾考虑过保持相同的列名,但这种方法避免了任何潜在的模棱两可的列名错误。带有表名缩写的列是我添加的代码,没有表名缩写的列是我正在使用的现有列。
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;