Кажется, я врезался в стену, пытаясь найти подходящий запрос для следующей базы данных (упрощенно):
userID userName
1 John
2 Jane
ПРИМЕЧАНИЕ: эта таблица станет довольно большой!
ingredientID ingredientName ingredientImage
1 Tomatoes tomato.png
2 Onions onion.png
3 Red Pepper redPepper.png
recipeID userID recipeName description
1 1 Tomato Sauce My homemade tomato sauce
2 1 Salsa Spicy Salse
3 2 Bruschetta Onion and Tomato Topping!
ПРИМЕЧАНИЕ: каждый рецепт может содержать не более 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
Я хочу быть в состоянии сделать запрос, чтобы перечислить все рецепты и дал бы мне следующие данные в строке.
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), но, похоже, не работает в этой ситуации, так как список ингредиентов в итоге будет очень большим (тогда как объекты в примере — довольно маленький набор).
РЕДАКТИРОВАТЬ
Какова лучшая практика для этого? Я вижу, что было бы проще вытащить рецепты, чем сделать вложенный цикл, чтобы вытащить ингредиенты, но это кажется интенсивным, особенно если число пользователей становится слишком большим. Я также рассмотрел вопрос о нормализации таблицы, но мне понадобятся данные, нормализованные для будущей аналитики / статистики, для потенциальных вопросов, таких как: сколько рецептов используют помидоры или что-то в этом роде.
У меня есть нормализованные таблицы, которые я хочу поместить в одну строку для отображения пользователю, и решение «MAX (CASE …») не работает для меня, так как набор данных будет очень большим
Вот пример использования нескольких LEFT JOIN
s. Присоединиться к пользователю довольно просто. Присоединение ингредиентов немного сложнее, так как вы должны присоединиться к RecipeIngredients
стол, а затем использовать этот идентификатор, чтобы присоединиться к ингредиенту. (обратите внимание, что это только первые 2 ингредиента, следующие / последние 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
Других решений пока нет …