Mysql JOIN多个表并选择多个值

时间:2012-06-14 15:54:54

标签: mysql join rows

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

  1. 分类
  2. 产品
  3. 规格
  4. Specificationvalues
  5. 每个类别都有规格和产品,每个规格值都有产品和规格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
    

    所以现在我想要所有黑色产品,尺寸为24x57x98。我希望你能帮助我!

2 个答案:

答案 0 :(得分: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' )

根据您修改过的示例数据...... 在您想要的这种类型的标准中,我会通过应用双连接来表示您想要的每个条件,例如:

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”作为第一个表,但第二个因为你可能有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)上有索引。这样,索引可以匹配您正在查找数据的方式。有些人甚至可能建议在(specifications_ID,value,products_id)索引中包含所有3个部分

答案 1 :(得分: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,具体取决于您的表格。

相关问题