[英]SQL Inner Join With Multiple Columns
I've got 2 tables - dishes and ingredients : 我有2张桌子- 菜肴和配料 :
in Dishes, I've got a list of pizza dishes, ordered as such: 在菜肴中,我有一份比萨饼清单,按以下顺序订购:
In Ingredients, I've got a list of all the different ingredients for all the dishes, ordered as such: 在“ 配料”中,我列出了所有菜肴的所有不同配料,并按以下顺序排列:
I want to be able to list all the names of all the ingredients of each dish alongside each dish's name . 我希望能够在每个菜名旁边列出每个菜的所有成分的所有名称 。
I've written this query that does not replace the ingredient ids with names as it should, instead opting to return an empty set - please explain what it that I'm doing wrong: 我写了这个查询,没有用名称替换成分ID,而是选择返回一个空集-请说明我做错了什么:
SELECT dishes.name, ingredients.name, ingredients.id
FROM dishes
INNER JOIN ingredients
ON dishes.ingredient_1=ingredients.id,dishes.ingredient_2=ingredients.id,dishes.ingredient_3=ingredients.id,dishes.ingredient_4=ingredients.id,dishes.ingredient_5=ingredients.id,dishes.ingredient_6=ingredients.id, dishes.ingredient_7=ingredients.id,dishes.ingredient_8=ingredients.id;
It would be great if you could refer to: 如果您可以参考:
Disregard The Text In Hebrew - Treat It As Your Own Language. 忽略希伯来语中的文本-将其视为您自己的语言。
It seems to me that a better Database Structure would have a Dishes_Ingredients_Rel table, rather than having a bunch of columns for Ingredients. 在我看来,更好的数据库结构将具有Dishes_Ingredients_Rel表,而不是具有一堆用于成分的列。
DISHES_INGREDIENTS_REL
DishesID
IngredientID
Then, you could just do a much simpler JOIN. 然后,您可以做一个简单得多的JOIN。
SELECT Ingredients.Name
FROM Dishes_Ingredients_Rel
INNER JOIN Ingredients
ON Dishes_Ingredients.IngredientID = Ingredients.IngredientID
WHERE Dishes_Ingredients_Rel.DishesID = @DishesID
1. The logic of the DB structuring - am I doing it correctly? 1.数据库结构的逻辑-我做对了吗?
Pizza
PizzaIngredients
Ingredients
Pizza
would have ID
, name
, and type
where ID
is the primary key. Pizza
将具有ID
, name
和type
,其中ID
是主键。
PizzaIngredients
would have PizzaId
and IngredientId
(this is a many-many table where the primary key is a composite key of PizzaId
and IngredientID
) PizzaIngredients
将具有PizzaId
和IngredientId
(这是一个很多表,其中主键是PizzaId
和IngredientID
的复合键)
Ingredients
has ID
and name
where ID
is the primary key. Ingredients
具有ID
和name
,其中ID
是主键。
2. List all the names of all the ingredients of each dish alongside each dish's name. 2.在每个菜名旁边列出每个菜所有成分的所有名称。 Something like this in
MySQL
(untested): 在
MySQL
(未经测试):
SELECT p.ID, p.name, GROUP_CONCAT(i.name) AS ingredients
FROM pizza p
INNER JOIN pizzaingredients pi ON p.ID = pi.PizzaID
INNER JOIN ingredients i ON pi.IngredientID = i.ID
GROUP BY p.id
3. If you've encountered such a problem before - one that requires a single-to-many relationship - how did you solved it in a way different than this, using PHP & MySQL? 3.如果以前遇到过这样的问题-需要单对多关系-您是如何使用PHP和MySQL以不同于此的方式解决此问题的?
The reason you are getting an empty result is because you are setting a join condition that never gets satisfied. 得到空结果的原因是因为您设置的连接条件永远不会满足。 During the INNER join execution the database engine compares each record of the first table with each record of the second one trying to find a match where the id of the ingredient table record being evaluated is equal to ingredient1 AND ingredient2 AND so on.
在执行INNER联接期间,数据库引擎会将第一个表的每个记录与第二个表的每个记录进行比较,以尝试找到匹配项,其中要评估的成分表记录的ID等于Ingredient1 AND Ingredient2等等。 It would return some result if you create a record in the first table with the same ingredient in all 8 columns (testing purposes only).
如果您在第一个表中创建的记录在所有8列中都具有相同的成分,则将返回一些结果(仅用于测试目的)。
Regarding the database structure, you choose a denormalized one creating 8 columns for each ingredient. 关于数据库结构,您选择一个非规范化的数据库,为每种成分创建8列。 There are a lot of considerations possible on this data structure (performance, maintainability, or just think if you are asked to insert a dish with 9 ingredients for example) and I would personally go for a normalized data structure instead.
在此数据结构上有很多考虑因素(性能,可维护性,或者仅考虑是否要求您插入包含9种成分的菜肴),我个人将使用标准化数据结构。
But if you want to keep this, you should write something like: 但是,如果要保留此内容,则应编写如下内容:
SELECT dishes.name, ingredients1.name, ingredients1.id, ingredients2.name, ingredients2.id, ...
FROM dishes
LEFT JOIN ingredients AS ingredients1 ON dishes.ingredient_1=ingredients1.id
LEFT JOIN ingredients AS ingredients2 ON dishes.ingredient_2=ingredients2.id
LEFT JOIN ingredients AS ingredients3 ON dishes.ingredient_3=ingredients3.id
...
The LEFT join is required to get a result for unmatched ingredients (0 value when no ingredient is set reading your example) 需要LEFT联接才能获得不匹配成分的结果(在您的示例中未设置任何成分时为0值)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.