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

复杂SQL查询字符串内部联接公共分母,sql,inner-join,Sql,Inner Join,这是一个非常重要的sql查询,我的整个网站都是基于这个查询的 而且它不起作用 没有例子很难解释 有两个表,一个是IngredientsTable,另一个是ProductsTable 在IngredentsTable中,我有以下内容 Select P.id, P.Name FROM ProductTable P Where Exists (Select * From Mapping Table Where ProductId = P.Product

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

而且它不起作用

没有例子很难解释

有两个表,一个是IngredientsTable,另一个是ProductsTable

在IngredentsTable中,我有以下内容

  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)
  • 面包
  • 胆小鬼
  • 面条
  • 蛋黄酱
  • 奶酪
  • 番茄酱
  • 黄油
  • 产品稳定

  • 斯帕盖蒂
  • 鸡胸肉三明治
  • 还有一个映射表连接两个表。它具有IngCreditID和ProductID

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

    鸡胸肉三明治-蛋黄酶

    鸡胸肉三明治-奶酪

    鸡胸肉三明治-番茄酱

    意大利面

    意大利干酪

    斯帕盖蒂-凯蒂杯

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

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

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

    SELECT 
      ProductTable.id,
      ProductTable.Name 
    FROM ProductTable 
    INNER JOIN MappingTable 
      ON ProductTable.id = MappingTable.ProductID
    WHERE MappingTable.IngredientID =  5; 
    
    假设5是奶酪,我成功地得到了鸡胸肉三明治和意大利面

    但如果我再加一个,其中MappingTable.IngredientID=5,66作为面包,它应该只给我看一个鸡胸肉三明治,而不是意大利面

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

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

    非常感谢您的帮助

    我需要在一个查询中得到这个

    请告诉我选项

    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
    

    您需要为每个成分分别链接到映射表:

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

    通过2个查询,你可以使用结果的INTERSECTION

    但是你说你想在一个查询中得到它

    近似的做法是使用GROUPBY语句并计算从结果中收到的行数。它必须和你们的配料量相等。但是,如果你的成分在同一产品中重复多次,它将不起作用

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

    首先,编辑您的问题,以便示例表中的数据与示例问题匹配。。。如果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)
    
    或者,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
    

    虽然您需要为其提供两个“变量”,但这应该是可行的——第一个是一组以逗号分隔的IngRedientId,第二个(@IngRedientScont)是该列表中的成分数

    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
    

    如果同一成分可以记录两次(虽然您的表结构看起来不允许,而且可能没有必要),请将两个计数(*)切换为计数(Distinct IngreditId),并将@IngreditCount更改为使用的不同成分的数量。

    我不这么认为。。。有了这个,任何5或6的产品都会通过,而不是5和6都通过。确定了问题,你得到了它,它在第一个查询中工作得很好,尽管不是反向逻辑