复杂的SQL查询字符串内部连接公共分母

时间:2009-08-31 12:56:23

标签: sql inner-join

这是一个非常非常重要的SQL查询,之后我的整个网站都是基于..

它不起作用..

没有一个例子很难解释..

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

IngredentsTable 中,我有以下

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

    1. Spageti
    2. 鸡胸肉三明治
    3. 并且有一个连接两个表的MAPPING TABLE。它有IngredientID和ProductID

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

      鸡胸肉三明治 - Mayonase

      鸡胸肉三明治 - 奶酪

      鸡胸肉三明治 - 番茄酱

      Spageti ---面条

      Spageti ---奶酪

      Spageti --- Ketcup

      您会注意到奶酪和番茄酱是鸡胸肉和Spageti的常见条目

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

      我可以使用以下查询部分实现它

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

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

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

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

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

      任何帮助都非常受欢迎!!!

      我需要在一个查询中使用它..

      请告诉我选项

5 个答案:

答案 0 :(得分:3)

使用2个查询,您可以使用结果的部分

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

近似将是group by语句和从结果中收到的行数。它必须等于你的成分量。如果你的成分在同一产品中重复多次,它将无法使用。

沿着这条线的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;

答案 1 :(得分: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

答案 2 :(得分:1)

首先,编辑你的问题,使你的示例表中的数据与示例问题相匹配......如果5是cheese而6是Bread,那么使Ingredients表匹配。否则会让人感到困惑。

其次,你说“,它应该只显示我的鸡胸肉三明治而不是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)

或,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

答案 3 :(得分: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类型查询。

答案 4 :(得分:0)

这应该有用,虽然你需要提供两个'变量' - 第一个是以逗号分隔的一组IngredientIDs,第二个(@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是使用的不同成分的数量。