SQL内连接多列

时间:2015-10-02 17:15:05

标签: mysql sql join inner-join

我有2张桌子 - 菜肴成分

菜肴我有一份披萨菜肴清单,按此订购: Dishes Table

成分中,我列出了所有菜肴的所有不同成分,按此订购:Ingredients Table

我希望能够列出每道菜的所有成分的名称以及每道菜的名称

我写过这个查询并没有用名称替换成分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;

如果您可以参考:

,那就太棒了
  1. 数据库结构的逻辑 - 我正确地做到了吗?
  2. SQL查询背后的逻辑 - 如果数据库是以正确的方式构建的,那么为什么在执行查询时我得到空集?
  3. 如果您以前遇到过这样的问题 - 需要一对多的关系 - 您是如何使用PHP和&以前的方式解决问题的? MySQL的?
  4. 无视希伯来文 - 将其视为自己的语言。

3 个答案:

答案 0 :(得分:2)

在我看来,一个更好的数据库结构将有一个 Dishes_Ingredients_Rel 表,而不是有一堆成分列。

class EntityDetail {
    String id;
    String name;
    String type;
}

然后,你可以做一个更简单的JOIN。

DISHES_INGREDIENTS_REL
DishesID
IngredientID

答案 1 :(得分:1)

<强> 1。数据库结构的逻辑 - 我正确地做到了吗?

  • 这是非规范化数据。要规范化它,您可以将数据库重组为三个表:
    • Pizza
    • PizzaIngredients
    • Ingredients

Pizza会有IDnametype,其中ID是主键。

PizzaIngredients会有PizzaIdIngredientId(这是一个多表,其中主键是PizzaIdIngredientID的复合键

IngredientsIDname,其中ID是主键。

<强> 2。列出每道菜的所有成分的名称以及每道菜的名称。 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。如果您之前遇到过这样的问题 - 需要单对多关系的问题 - 您是如何使用PHP&amp; MySQL的吗

  • 使用许多关系,因为那是你的榜样。你有很多比萨饼可以有很多成分。许多成分属于许多不同的比萨饼。

答案 2 :(得分:1)

您获得空结果的原因是因为您正在设置永远不会满足的连接条件。在INNER连接执行期间,数据库引擎将第一个表的每个记录与试图找到匹配的第二个记录进行比较,其中被评估的成分表记录的id等于成分1和成分2,依此类推。如果您在第一个表中创建一个记录,并且在所有8列中都使用相同的成分,则会返回一些结果(仅用于测试目的)。

关于数据库结构,您选择一个非规范化的结构,为每个成分创建8列。在这个数据结构上有很多可能的考虑因素(性能,可维护性,或者只是考虑一下你是否被要求插入含有9种成分的菜肴),我个人会寻求标准化的数据结构。

但是如果你想保留这个,你应该写一些类似的东西:

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
...

LEFT join是获得不匹配成分的结果所必需的(如果未设置任何成分,则为0值)