2009-08-31 68 views
3

这之后,我的整个网站是基于一个非常非常重要的SQL查询..复杂的SQL查询字符串内加入共同点

和它不工作..

其难度没有一个例子来解释..

有2个表,一个是IngredientsTable,另一个是ProductsTable。

IngredentsTable我有以下

  1. 面包
  2. ChickenBreast
  3. 面条
  4. Mayonaise
  5. 奶酪
  6. 番茄酱
  7. 黄油

而且ProductsTable

  1. Spageti
  2. 鸡胸三明治

还有是连接两个表的映射表。它有IngredientID和产品ID

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

鸡胸三明治 - Mayonase

鸡胸三明治 - 奶酪

鸡胸三明治 - 番茄酱

Spageti ---面条

Spageti ---奶酪

Spageti --- Ketcup

你会发现,奶酪和番茄酱是既鸡胸肉和Spageti

常见条目我想写一个SQL查询,得到具有特定成分的产品的编号。

我能够用下面的查询部分实现它

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

假设5是奶酪,我能够成功获得鸡胸三明治的结果和Spageti

但如果我添加另外,WHERE MappingTable。成分ID = 5,6; 6是面包,它应该只显示我一个鸡胸肉三明治,而不是Spageti

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

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

任何帮助都非常赞赏!

我需要有这样一个单一的查询..

请告诉我选择

回答

3

随着2个查询,你可以使用你的结果

的intesection但是你说你想在一个查询。

一个近似的近似值应该是按结果分组的语句和计数的行数。它必须等于你的原料的数量。如果您的配料在同一产品中重复使用不止一次,它将不起作用。

东西沿着这条线2个成分标识:

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; 
+0

This works too :)谢谢dimus – user134611 2009-08-31 14:04:28

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 
+1

我不这么认为......有了这个任何产品5或6将通过,而不是与5和6两个 – 2009-08-31 13:05:09

+0

它不这样工作.. IS SQLite负责? – user134611 2009-08-31 13:08:18

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型查询。

1

首先,编辑您的问题,以便在您的示例表中的数据的例子匹配的问题......如果5是奶酪和6是面包,然后使配料表匹配。否则会令人困惑。其次,你要说的是,“它只应该给我看一个鸡胸肉三明治而不是Spageti”,这让我想你想知道那些包含所有列出的食品添加剂的产品,而不是其中的任何一个。如果是的话,你希望达到以下

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) 

,或者us8ng计数逻辑:

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 
+0

编辑了这个问题,并且你懂了,它对第一个查询很有帮助,尽管没有反向逻辑 – user134611 2009-08-31 13:29:52

0

这应该工作,虽然你需要提供两个“变量”来了 - 首先是一个逗号分隔一组IngredientID,第二个(@IredredientsCount)是该列表中成分的数量。

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(*),伯爵(不同IngredientID)并将@IngredientCount更改为所用不同配料的数量。