2011-06-07 33 views
4

我试图根据产品类别页面的方面来选择产品。在MySQL中拥有子查询仍然困惑

的基本结构是:

 
Product_Facets 
-------------------------------- 
UID  ProductID  FacetID  FacetOptionID 
1   1    1    1 
2   1    1    2 
3   1    2    4 
4   1    2    7 
 
Products 
-------------------------------- 
ProductID  ProductName 
    1   Some Widget 

我想选择其中有一个小记录设置为正确的值ALL用户选择方面的所有产品。

所以,如果我有一个请求:
刻面ID 1设置为值是6而
刻面ID 2设定为值97和
刻面ID 5设定为值43和

我想要的查询以从产品表中获得所有产品的facet表中的所有产品记录的ALL。该查询不应返回仅满足某些要求的产品。

我想我需要做一个子查询里面的having子句,但我不知道如何得到结构?

+0

你的意思 刻面ID 1具有FacetOptionID 6和 刻面ID 2已经FacetOptionID 97和 刻面ID 5有FacetOptionID ? – CristiC 2011-06-07 15:00:44

回答

3

一种方法将使用EXISTS子句,你可以生成动态地基于该请求:

select p.* 
from Products p 
where 
    exists (select 1 from Product_Facets where ProductID = p.ProductID 
             and FacetID = 1 
             and FacetOptionID= 6) 
and 
    exists (select 1 from Product_Facets where ProductID = p.ProductID 
             and FacetID = 2 
             and FacetOptionID= 97) 
and 
    exists (select 1 from Product_Facets where ProductID = p.ProductID 
             and FacetID = 3 
             and FacetOptionID = 43) 

另一种方法是平直的内连接(也容易动态生成):

select p.* 
from Products p 
join Product_Facets f1 on p.ProductID = f1.ProductID 
     and f1.FacetID = 1 and f1.FacetOptionID = 6 
join Product_Facets f2 on p.ProductID = f2.ProductID 
     and f2.FacetID = 2 and f2.FacetOptionID = 97 
join Product_Facets f3 on p.ProductID = f3.ProductID 
     and f3.FacetID = 3 and f3.FacetOptionID = 43 

任何一种方法都只会返回产品的记录,其中每个请求的FacetID和FacetOptionID都存在Product_Facets记录(我认为这是您提到的值字段)。

+0

这似乎很好,谢谢! – Nick 2011-06-07 17:10:43

0

我只会从facet表中预先查询那些匹配并应用HAVING count的实体,它们完全等于您选择的条件,然后将其加入到产品表中。

第一个“PreQuery”将“OR”应用于每个组合,作为单独测试每一行......但HAVING子句确保ALL 3条件具有适当的限定条件。

SELECT STRAIGHT_JOIN 
     P.* 
    FROM 
     (select pf.ProductID, 
       count(*) as MatchedCriteria 
      from 
       Product_Facets pf 
      where 
       (pf.FacetID = 1 AND FacetOptionID = 6) 
       OR (pf.FacetID = 2 AND FacetOptionID = 97) 
       OR (pf.FacetID = 5 AND FacetOptionID = 43) 
      group by 
       pf.ProductID 
      having 
       count(*) = 3) PreQuery 

     Join Products p 
     on PreQuery.ProductID = p.ProductID 
    order by 
     p.ProductName