3

这是一个非常重要的 sql 查询,我的整个网站都基于它。

它不工作..

没有例子很难解释..

有 2 个表,一个是成分表,另一个是产品表。

IngredentsTable我有以下

  1. 面包
  2. 鸡胸肉
  3. 面条
  4. 蛋黄酱
  5. 起司
  6. 番茄酱
  7. 黄油

ProductsTable

  1. 斯帕蒂
  2. 鸡胸肉三明治

并且有一个连接两个表的映射表。它有 IngredientID 和 ProductID

现在,映射表 鸡胸肉三明治 - 面包

鸡胸肉三明治 - 蛋黄酱

鸡胸肉三明治 - 奶酪

鸡胸肉三明治 - 番茄酱

Spageti --- 面条

Spageti --- 奶酪

Spageti --- 番茄酱

你会注意到奶酪和番茄酱是鸡胸肉和意大利面的常见条目

我想编写一个 sql 查询来获取具有指定成分的产品的 ID。

我可以通过以下查询部分实现它

SELECT 
  ProductTable.id,
  ProductTable.Name 
FROM ProductTable 
INNER JOIN MappingTable 
  ON ProductTable.id = MappingTable.ProductID
WHERE MappingTable.IngredientID =  5; 

假设 5 是奶酪,我成功地获得了鸡胸肉三明治和意大利面的结果

但如果我再添加一个, WHERE MappingTable.IngredientID = 5,6; 6 是面包,它应该只给我看一个鸡胸肉三明治而不是 Spageti

我收到错误“,”语法..甚至“和”也没有得到结果。

如何检查多个成分,例如WHERE MappingTable.IngredientID = 5,6,7;

任何帮助是极大的赞赏!!!

我需要在一个查询中拥有这个..

请告诉我选项

4

5 回答 5

3

通过 2 个查询,您可以使用结果的交集

但是你说你想要它在一个查询中。

一个接近的近似值是按语句分组并计算从结果中收到的行数。它必须等于您的成分的数量。但是,如果您的成分在同一产品中重复多次,它将不起作用。

沿着这条线的 2 个成分 ID:

SELECT ProductTable.id, ProductTable.Name FROM ProductTable 
INNER JOIN MappingTable ON ProductTable.id = MappingTable.ProductID 
WHERE MappingTable.IngredientID in (5,6) group by ProductTable.id, ProductTable.Name 
HAVING count(*) = 2;
于 2009-08-31T13:07:37.717 回答
1
WHERE MappingTable.IngredientID IN (5, 6, 7)

对不起这是我的错。这个怎么样?:

SELECT 
  p.id,
  p.Name 
FROM ProductTable p
INNER JOIN (SELECT * FROM MappingTable WHERE IngredientID IN (5, 6, 7)) m
  ON p.id = m.ProductID
于 2009-08-31T12:59:47.070 回答
1

首先,编辑您的问题,使示例表中的数据与示例问题相匹配...如果 5 是奶酪,6 是面包,则使成分表匹配。否则会令人困惑。

其次,你说“,它应该只给我看一个鸡胸肉三明治而不是 Spageti”让我觉得你想知道含有所有列出的 ingfrediants 的产品,而不是其中的任何一个。如果是这样,那么你想要以下

  Select P.id,  P.Name 
  FROM ProductTable P 
  Where Exists (Select * From Mapping Table
                Where ProductId = P.ProductId
                    And IngredientId = 5)
    And Exists (Select * From Mapping Table
                Where ProductId = P.ProductId
                    And IngredientId = 6)
    And Exists (Select * From Mapping Table
                Where ProductId = P.ProductId
                    And IngredientId = 7)

或者,使用计数逻辑:

   Select P.id,  P.Name 
   From ProductTable P 
   Where (Select Count(Distinct IngredientId)
          From MappingTable M
          Where ProductId = P.ProductId 
            And IngredientId In (5,6,7)) = 3
于 2009-08-31T13:10:34.753 回答
0

您需要为每种成分单独链接到映射表:

SELECT 
  ProductTable.id,
  ProductTable.Name 
FROM ProductTable 
INNER JOIN MappingTable AS MappingTable1
  ON ProductTable.id = MappingTable1.ProductID
  AND MappingTable1.IngredientID = 5
INNER JOIN MappingTable AS MappingTable2
  ON ProductTable.id = MappingTable2.ProductID
  AND MappingTable2.IngredientID = 6

如果您按照其他发帖人的建议使用 IN 运算符,您将获得用于面包和奶酪的意大利面条和鸡肉三明治,因为 IN 本质上是一个 OR 类型的查询。

于 2009-08-31T13:06:29.273 回答
0

这应该可以工作,尽管您需要为其提供两个“变量”——第一个是逗号分隔的成分 ID 集,第二个 (@IngredientsCount) 是该列表中成分的数量。

SELECT ProductsTable.id, ProductTable.Name
FROM ProductsTable
INNER JOIN (SELECT ProductID, Count(*) AS Ingredients
    FROM MappingTable
    WHERE IngredientID IN (...ids of ingredients here...)
    GROUP BY ProductID
    HAVING Count(*) = @IngredientsCount) AS ProductIngredients ON ProductsTable.ProductID = ProductIngredients.ProductID

如果同一成分可能被记录两次(尽管您的表结构看起来不允许这样做,并且可能没有必要),请将两个 Count(*) 切换为 Count(Distinct IngredientID) 并将 @IngredientCount 更改为是使用的不同成分的数量。

于 2009-08-31T13:20:13.277 回答