1

我有 2 张桌子:食物和成分。我想选择制作某些食物所需的所有成分。

我以为我可以做这样的事情:

select NAME from INGREDIENTS
 where ID in (select ING1_ID, ING2_ID, ING3_ID from FOOD where NAME = 'Meat soup')

这显然不起作用,因为我需要在“in”子选择查询中传递一串逗号分隔的 ID。我正在考虑将列值列表转换为字符串,并且有一些解决方案,但我开始认为也许我过于复杂了,而且我的数据库模型是错误的。

食物表:

ID      | NAME          | ING1_ID  | ING2_ID  | ING3_ID
--------+---------------+----------+----------+--------
1       | Meat soup     | 1        | 2        | 3
2       | Pasta Bolo    | 3        | 4        | 5
3       | Chicken salad | 2        | 4        | 5

成分表:

ID      | NAME          
--------+-----------
1       | pasta     
2       | onion   
3       | oil 
4       | paprika 
5       | chicken 
6       | cucumber 
4

3 回答 3

7

许多菜肴的成分超过三种,当您搜索时,您并不关心给定成分是#1 还是#2 或#3。

所以更好的模型是

FOOD
id | name
1  | meat soup


INGREDIENTS
id | name 
1  | meat  

FOOD_INGREDIENTS
food_id | ingredients_id
1       | 1

现在您的查询只是

select i.name from ingredients i, food f, food_ingredients fi
where fi.food_id = f.id
and fi.ingredients_id = i.id
and f.name = "meat soup"

“food_ingredients”表通常称为“连接表”。连接表的另一个好处是您可以添加特定于某种食物中特定成分的信息(例如数量或应如何准备)。

于 2012-06-17T18:22:15.117 回答
3

您的问题源于您没有标准化数据模型这一事实。

你应该重新设计成这样的:

食物表:

  • 食物编号
  • 姓名

成分表:

  • 编号
  • 姓名

FOOD2INGREDIENTS 表:

  • 食物编号
  • 编号
  • (在这里添加数量会很有意义)

一旦进行了这样的重新设计,您只需通过以下查询即可获得所需的内容:

SELECT i.ID, I.Name 
FROM Ingredients I 
 INNER JOIN Food2Ingredients F2I 
 ON I.IngID = F2I.IngID
WHERE
  F2I.FoodID = :foodid;
于 2012-06-17T18:27:29.777 回答
2

只要您所有的食谱都如此贫乏以至于只需要三种成分,那么您就可以通过编写原始查询来解决问题:

SELECT Name FROM Ingredients
 WHERE ID IN (SELECT ING1_ID FROM Food WHERE Name = 'Meat soup'
              UNION
              SELECT ING2_ID FROM Food WHERE Name = 'Meat soup'
              UNION
              SELECT ING3_ID FROM Food WHERE Name = 'Meat soup'
             )

但是,我认为JacobMKerbocat在数据库重新设计方面的想法是正确的,并且您认为您的数据库设计存在问题的感觉值得称赞。请注意,如果您需要一个包含 4 种(或更多)成分的配方,您将面临当前设计的灾难(例如,因为您必须编辑所有现有 SQL,其中包括如上所示的多路 UNION 操作),但重新设计的模式甚至不会注意到。

于 2012-06-17T18:31:59.560 回答