规范化 MySQL 将数据透视/行转换为没有唯一名称的列

Normalized MySQL Pivot / Rows to Columns without unique names

我在尝试为以下数据库(简化版)找出合适的查询时似乎碰壁了:

'Users' Table

userID    userName
1         John
2         Jane

'Ingredients' Table

注意:这个 table 会变得相当大!

ingredientID     ingredientName     ingredientImage
1                Tomatoes           tomato.png
2                Onions             onion.png
3                Red Pepper         redPepper.png

'Recipes' Table

recipeID     userID     recipeName     description
1            1          Tomato Sauce   My homemade tomato sauce
2            1          Salsa          Spicy Salse
3            2          Bruschetta     Onion and Tomato Topping!      

'RecipeIngredients' Table

注意:每个配方最多只能有 5 种成分,这将在创建配方(插入期间)时受到限制

recipeIngredientID     recipeID     ingredientID     amount
1                      1            1                3
2                      2            1                2
3                      2            2                1
4                      3            1                2
4                      3            2                1
4                      3            3                2

我需要什么

我希望能够执行查询以列出所有食谱,并为我提供每行以下数据。

我正在寻找的示例

我正在寻找的 table 格式的示例

RecipeID    RecipeName    RecipeDescription           UserID    UserName    Ingredient1    Ingredient1Image    Ingredient1Amount    Ingredient2    IIngredient1Image    Ingredient2Amount    Ingredient3    Ingredient1Image    Ingredient3Amount    Ingredient4    Ingredient1Image    Ingredient4Amount    Ingredient5    Ingredient1Image    Ingredient5Amount
1           Tomato Sauce  My homemade tomato sauce    1         John        Tomatoes       tomato.png          3                    NULL           NULL                 NULL                 NULL           NULL                NULL                 NULL           NULL                NULL                 NULL           NULL                NULL
2           Salsa         Spicy salsa                 1         John        Tomatoes       tomato.png          2                    Onions         onion.png            1                    NULL           NULL                NULL                 NULL           NULL                NULL                 NULL           NULL                NULL
3           Bruschetta    Onion and Tomato Topping    2         Jane        Tomatoes       tomato.png          2                    Onions         onion.png            1                    Red Pepper     redPepper.png       2                    NULL           NULL                NULL                 NULL           NULL                NULL

帮助

如有任何帮助,我们将不胜感激。我已经查看了 'MAX(CASE ...' 语句(如此处所示 https://dba.stackexchange.com/questions/47902/how-to-transpose-convert-rows-as-columns-in-mysql),但在这种情况下似乎不起作用,因为成分列表最终会非常大(示例中的主题是相当小的一组)。

编辑 这方面的最佳做法是什么?我看到拉出食谱然后做一个嵌套循环来拉出配料会更简单,但这似乎很密集,尤其是在用户数量太大的情况下。我还考虑过对 table 进行去规范化,但我需要为将来 analytics/statistics 对数据进行规范化,以解决潜在的问题,例如:有多少食谱使用西红柿或类似的东西。

TL;DR

我已经规范化了 tables,我想在一行中显示给用户,'MAX(CASE...' 解决方案对我不起作用,因为数据集会非常大

这是一个使用多个 LEFT JOIN 的示例。加入用户非常简单。加入成分有点复杂,因为您必须先加入 RecipeIngredients table,然后使用该 ID 加入成分。 (注意这只有前 2 个成分,next/last 3 个可以用同样的方法完成)

SELECT 
    r.recipeID, r.recipeName, r.description, 
    u.userID, u.userName,
    I1.ingredientName as Ingredient1, I1.ingredientImage as Ingredient1Image, rI1.amount as Ingredient1Amount,
    I2.ingredientName as Ingredient2, I2.ingredientImage as Ingredient2Image, rI2.amount as Ingredient2Amount
FROM
    Recipes r
LEFT JOIN 
    Users u 
ON 
    u.userID = r.userID

/*First Ingredient*/
LEFT JOIN 
    RecipeIngredients rI1 
ON 
    rI1.recipeIngredientID = (
      SELECT 
          rIa.recipeIngredientID 
      FROM RecipeIngredients rIa 
      WHERE rIa.recipeID = r.recipeID ORDER BY rIa.recipeIngredientID LIMIT 0,1 )
LEFT JOIN 
    Ingredients I1 
ON 
    I1.ingredientID = rI1.ingredientID

/*Second Ingredient*/
LEFT JOIN 
    RecipeIngredients rI2 
ON 
    rI2.recipeIngredientID = (
      SELECT 
          rIb.recipeIngredientID 
      FROM RecipeIngredients rIb 
      WHERE rIb.recipeID = r.recipeID ORDER BY rIb.recipeIngredientID LIMIT 1,1 )
LEFT JOIN 
    Ingredients I2 
ON 
    I2.ingredientID = rI2.ingredientID

这是一个有效的 sqlFiddle - http://sqlfiddle.com/#!2/3215e1/6