2

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

  1. 类别
  2. 产品
  3. 规格
  4. 规格值

每个类别都有规格和产品,每个规格值都有产品和规格 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 的黑色产品。我希望你能帮帮我!

4

2 回答 2

5

我见过许多表的实例,这些表具有模拟表示“列”的行,其中名称是描述符,而“id”或“值”是关联的所需值。

您需要考虑的是 ONE ROW 的外观。您从规格名称到规格值的连接。'77' 值是否仅对应于 'material' 规格、'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(代码列表)和 IN(值列表)并使用 HAVING 子句确保找到正确计数的匹配元素。我的 FINAL 查询不会使用“产品”作为第一个表,而是第二个,因为您可以拥有 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) 的索引中

于 2012-06-14T17:09:47.023 回答
0

那不是因为all the values are in separate rows,那是因为您的 WHERE 子句始终为 false :

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

你不能拥有和 id 等于 77 AND 78。

您必须使用这种代码:

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

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

于 2012-06-14T16:00:22.963 回答