我有一个网站,其产品已添加到类别中。这些类别按层次排名。因此,产品是该类别的成员以及此类别的所有父母。我们有一个搜索索引表,如下所示:
product_id | category_level_1 | category_level_2 | category_level_3 | property_a | property_b
--------------------------------------------------------------------------------
1 | category1 | category2 | category3 | 1 | 2
2 | category1 | category2 | category4 | 1 | 3
如果我在产品搜索索引表上运行查询过滤某些属性(例如propery_a和property_b),我也想知道最小公分母类别是什么。在上面的示例category2。
我有一个工作查询,它会将结果集返回给我的应用程序,包括列category_level_1,category_level_2和category_level_3。循环遍历结果集时,我可以确定最小公分母类别。
但是,如果我可以确定第一个查询中的最小公分母,这将为我节省大量数据传输(类别树在现实生活中最多可达9个级别)。有没有人有一个建议如何确定查询中的公共类别也过滤属性(WHERE property_a = 1)?
根据ARTM的答案,我的解决方案最终是:
现实情况更复杂但你让我走上了正确的道路!谢谢!关于属性的查询可能非常复杂:WHERE(property_a = 1 AND(Property_2 = 2或Peroperty_2)= 3 AND Property_3 = 4)等。 让我们称之为" property_query"。
我让这个工作:
SELECT product_id, category as common_category FROM ( SELECT Product_id, COUNT(*) OVER (PARTITION BY 1) AS productCount FROM <tablename> WHERE <property_query>)) A INNER JOIN (
select count(*) as categoryCount , category
from (select category_level_1 as cat, from <tablename> WHERE <property_query>
union all select category_level_2, from <tablename> WHERE <property_query>
union all select category_level_3, from <tablename> WHERE <property_query>)c
group by cat ) B ON B.categoryCount = A.productCount
现在我必须测试它的性能......
答案 0 :(得分:1)
您可以获得所有类别列的并集,其中property_a是您要查找的内容,并获取按类别分组的计数。然后,您可以加入另一个内部选择,其中具有搜索条件的行数与按每个类别分组的计数相同。
SELECT product_id, cat AS CommonDeno
FROM (
select COUNT(*) OVER (PARTITION BY property_a) AS ProductCountWithProperty_A
, product_id
, pr.property_a
from yourTable
) A
INNER JOIN (select count(*) as catCount
, cat
from (
select category_level_1 as cat, property_a as p from yourTable
union all select category_level_2, property_a from yourTable
union all select category_level_3, property_a from yourTable
) c
where c.p = 1
group by cat
) i on i.catCount = A.ProductCountWithProperty_A
AND A.property_a = 1
答案 1 :(得分:0)
首先,您不需要在第二步中循环结果集。
with result(product_id, category_level_1 , category_level_2 , category_level_3, property_a , property_b) as
(
--your first query here
)
select denominator=
case min(category_level_1) when max(category_level_1) then min(category_level_1) +
case min(category_level_2) when max(category_level_2) then min(category_level_2) +
case min(category_level_3) when max(category_level_3) then min(category_level_3) else '' end else '' end end
from result
having min(category_level_1) = max( category_level_1)
接下来,如果您使用的是sql 2014,那么您可以将此逻辑合并到第一个查询中,并使用窗口max() over(), min() over()