2012-06-14 44 views
2

首先,我想为我的糟糕英语道歉。我有多个表的问题。 我并不是mySQL世界中的新手,但我无法找出解决这个问题的方法。 对于这个问题我使用4个表格。Mysql JOIN多个表并选择多个值

  1. 分类
  2. 产品
  3. 规格
  4. Specificationvalues

每个类别都有规格和产品,每specificationvalues拥有的产品和规范的ID。 现在用户可以使用不同的值进行选择。 这是我的问题所在。 当用户选择价值“绿色”和腿“4”我想要所有4条腿的绿色产品。 所以我用一个JOIN(各种我认为)来选择合适的产品(如下所示)

SELECT DISTINCT products.id 
FROM products 
    LEFT JOIN specificationvalues ON specificationvalues.products_id = products.id 
    LEFT JOIN specifications ON specificationvalues.specifications_id = specifications.id 
WHERE specifications.name='materiaal' 
    AND specifications.name='kleur' 
    AND specificationvalues.id='77' 
    AND specificationvalues.id='78' 

的问题是,所有的值都在不同的行。这就是为什么WHERE不起作用。我没有得到MySQL错误。只有它返回0行。

我希望有人能帮助我!我从这个论坛得到了很多好东西,所以我希望它能帮助我!


我不知道为什么我的改动昨天没有保存。但这里是我的数据再次:

SPECIFICATIONS Table 
ID CATEGORIES_ID  NAME 
38 297    Material 
39 297    Measures 
40 297    Color 

SPECIFICATIONVALUES Table 
ID SPECIFICATIONS_ID PRODUCTS_ID VALUE 
1 38     988979  Masive wood 
2 39     988979  24x57x98 
3 40     988979  Yellow 
4 40     988980  Black 
5 39     388980  24x57x98 


PRODUCTS Table 
ID   NAME 
988979  Table 
988980  Chair 

所以现在我想所有黑色prducts与措施24x57x98。我希望你可以帮助我!

回答

5

我见过很多表格有行模拟代表“列”的地方,其中名称是描述符,“id”或“value”是关联的希望值。

你需要考虑的是ONE ROW的样子。从规格名称到规格值的加入。 77的值只对应于'材料'规格,'kleur',或者两者都是......同样是78。你可以有多种组合,如

where (specifications.name = 'material' and specificationValues.id = '77') 
    OR (specifications.name = 'kleur' and specificationValues.id = '78') 

或者,如果标准值的ID,无论是规范的名字,你可以使用

where specifications.name in ('material', 'kleur') 
    AND speciificationValues.ID in ('77', '78') 

PER修改后的样本数据.. 在这种类型的标准你想,我会通过应用双连接来表示你想要的每个标准,如:

select p.*, 
     sv1.Value as NameOfColor, 
     sv2.Value as ProductMeasurement 
    from 
     Products p 

     JOIN SpecificationValues sv1 
      on p.ID = sv1.products_id 
      AND sv1.Value = 'Black' 
      JOIN Specifications s1 
       on sv1.Specifications_ID = s1.ID 
       AND s1.Name = 'Color' 

     JOIN SpecificationValues sv2 
      on p.ID = sv2.products_id 
      AND sv2.Value = '24x57x98' 
      JOIN Specifications s2 
       on sv2.Specifications_ID = s2.ID 
       AND s2.Name = 'Measures 

现在,看起来很复杂,但看看简单性(通过连接段之间的显式间距)。然而,如果你想添加更多的“crieria”需求,只需创建一个类似的sv3,sv4,sv5集合就可以复制......现在,这就是说,如果你在用户可以挑选更多东西的地方动态地构建这个,并且您正在提供某种“可选描述”(颜色,度量,材质)的“选择”,然后只保留这些ID,这样您就不需要额外的连接,只需知道实际的ID,就可以简化为.. 。

select p.*, 
     sv1.Value as NameOfColor, 
     sv2.Value as ProductMeasurement 
    from 
     Products p 

     JOIN SpecificationValues sv1 
      on p.ID = sv1.products_id 
      AND sv1.Specifications_ID = 40 
      AND sv1.Value = 'Black' 

     JOIN SpecificationValues sv2 
      on p.ID = sv2.products_id 
      AND sv2.SpecificationsID = 39 
      AND sv2.Value = '24x57x98' 

现在,回到原来的答案,你可以得到相同的结果(前提是你从来没有的“24x57x98”颜色,或“黑色”的根据您的示例数据的测量,你可以将IN (代码列表)AND IN(值列表)并使用HAVING子句确保找到匹配元素的正确计数。我的FINAL查询不会使用“Products”作为fi第一个表,但第二个表,因为你可以有10,000个产品,但只有142个具有给定的大小......从一个较小集合的表/标准开始,并加入到产品中以获得名称。

select 
     p.id, 
     p.name 
    from 
     specificationValues sv 
     join products p 
      on sv.products_id = p.id 
    where 
      sv.specifications_ID IN (39, 40) 
     AND sv.value in ('Black', '24x57x98') 
    group by 
     p.id 
    having 
     count(*) = 2 

确保您的specificationValues表具有(specifications_ID,value)上的索引。这样,索引可以匹配你如何查找数据。有些人甚至可能会建议索引中的所有3个部分(specifications_ID,value,products_id)

+0

您的天才!感谢您的帮助DRapp!这就是解决方案 – raice

+0

@ user1456684,作为一个新手,当你有一个问题并得到一个解决方案时,向提供解决方案的人提供一个解决方案来检查它,并在答案旁边打上复选标记。这告诉其他人你的问题已经解决了,什么答案有效。这有助于未来可能会遇到类似问题的其他人以及可能对他们有用的DID。 – DRapp

+0

我很抱歉,但仍然有一个问题。当我选择2个值时,我仍然得到匹配2个值中的1个的产品。甚至当我使用AND时。 – raice

0

这并不是因为all the values are in separate rows,那是因为你的WHERE子句永远是假的:

WHERE specifications.name='materiaal' AND specifications.name='kleur' 
AND specificationvalues.id='77' AND specificationvalues.id='78' 

你不能和id等于77和78

您必须使用这种代码:

WHERE (specifications.name='materiaal' OR specifications.name='kleur') 
AND (specificationvalues.id='77' OR specificationvalues.id='78') 

编辑:我最后AND可能也将会是一个OR,这取决于你的表。