2016-06-22 32 views
2

我想知道是否有可能使用单个mysql查询来完成某些操作,如果是这样,那么对最有效的方式感兴趣做到这一点。SQL:返回具有给定项目的值的子集的项目的查询

我有两个字段的表...让我们说配方成分

我正在寻找具有给定配方的成分的子集所有的食谱。

为了说明:

Recipe | Ingredient 
------------------- 
sandwich | bread 

sandwich | lettuce 

sandwich | mustard 

sandwich | bacon 

sandwich | tomato 

bacon salad | lettuce 

bacon salad | tomato 

bacon salad | bacon 

veggie salad | lettuce 

veggie salad | tomato 

veggie salad | cucumber 

我传递“三明治”作为参数,并需要一个查询将返回培根沙拉(即成分都包含在夹层的列表成分),但不是蔬菜沙拉,因为它含有黄瓜,这不在三明治中。

我查看了这个问题:

SQL query to exclude records that appear in other rows?

,但我认为我的情况是不同的,更加复杂。如果我传递“培根”并排除所有包含“培根”以外的成分的食谱,这将是类似的,但我需要根据输入配方成分的查询生成我排除的内容列表。

希望有道理!我觉得这应该是相当平凡的,但我坚持。

TIA为您提供帮助!

+0

我不知道你是否能在MySQL中做到这一点,但在SQL Server中,为连接到子选择,或者使用/ CTE定义,这将是微不足道的表 – Nikki9696

+0

谢谢,@ Nikki9696。你能为我的例子建议一个SQLServer查询吗?我会看看它是否会与MySQL一起工作。 – Sofia

回答

0

可以说,表名是kitchen

select * from kitchen k0 where Recipe NOT IN 
(
select * from kitchen k1 where Recipe!="sandwitch" and 
ingredient NOT IN (select k2.ingredient from kitchen k2 where Recipe="sandwitch")) 

说明:

  • 查找具有ATLEAST一种成分是不是“sandwitch”的成分
  • 现在发现在菜谱食谱该表不在以上的配方集合中。
+0

谢谢!这也适用于一些调整。我认为这比@Gordon Linoff快一点,但很难说,因为我的桌子很小。 – Sofia

2

你想统计相同成分的数量。您可以使用left join和聚集做到这一点:

select i.recipe 
from ingredients i left join 
    ingredients i2 
    on i.ingredient = i2.ingredient and i2.recipe = 'sandwich' and 
     i.recipe <> i2.recipe 
group by i.recipe 
having count(*) = count(i2.ingredient); 

having子句会检查所有成分有sandwich匹配。

+0

谢谢!!!!!我将不得不做一些测试,但我认为这是完美:) – Sofia

0

可能是你需要一个内部联接

select distinct a.Recipe 
from my_table as a 
inner my_table as b on a.ingredient = b.ingredient; 
0

这适用于SQL Server中。我相信有在MySQL中的等价

Drop Table #Test1 
Create Table #Test1 (Recipe Varchar(8000), Ingredient Varchar(8000)) 

Insert #Test1 Values ('sandwich', 'bread') 
Insert #Test1 Values ('sandwich', 'lettuce') 
Insert #Test1 Values ('sandwich', 'mustard') 
Insert #Test1 Values ('sandwich', 'bacon') 
Insert #Test1 Values ('sandwich', 'tomato') 
Insert #Test1 Values ('bacon salad ', 'lettuce') 
Insert #Test1 Values ('bacon salad ', 'tomato') 
Insert #Test1 Values ('bacon salad', 'bacon') 
Insert #Test1 Values ('veggie salad', 'lettuce') 
Insert #Test1 Values ('veggie salad', 'tomato') 
Insert #Test1 Values ('veggie salad', 'cucumber') 

;With cteQuery As 
(
Select T.*, A.Ingredient IngredientMatch 
    From #Test1 T 
    Left Join (
     Select Ingredient 
      From #Test1 
      Where Recipe = 'Sandwich' 
     ) A On A.Ingredient = T.Ingredient 
    Where Recipe != 'Sandwich' 
) 
Select Distinct Recipe From cteQuery Where Recipe Not In 
    (Select Recipe From cteQuery Where IngredientMatch Is Null) 
相关问题