UPDATE / EDIT:
Обновлено для корректного расчета количества
Я изменил вашу таблицу, чтобы лучше соответствовать данным, которые вы пытаетесь представить. Поскольку «рецепт» также может быть «материалом», я удалил таблицу рецептов и сохранил эти данные в таблице материалов.
Я также создал скрипту SQL, чтобы вы могли поиграть с запросом и настроить результаты.
Первый запрос ниже возвращает все «рецепты» и их компоненты. Чтобы получить только один конкретный рецепт, просто добавьте условие к предложению where, которое выбирает конкретный рецепт.
Если вы предпочитаете, чтобы компоненты были перечислены в одном поле, с одной строкой на рецепт, вы можете использовать функцию GROUP_CONCAT и изменить выражение group by.
Второй запрос ниже иллюстрирует функцию GROUP_CONCAT. Также показано, как изменить отсутствующие суб-ингредиенты с NULL на None
SQL Fiddle
Настройка схемы MySQL 5.6 :
CREATE TABLE `Ingredients`
(
`MaterialID` INT unsigned NOT NULL AUTO_INCREMENT,
`Material` VARCHAR(250) NOT NULL,
`MaterialImage` VARCHAR(250),
`IsRecipe` TINYINT(1) DEFAULT 0 NULL,
PRIMARY KEY (`MaterialID`)
);
CREATE TABLE `Recipes_Ingredients`
(
`id` INT unsigned NOT NULL AUTO_INCREMENT,
`RecipeID` INT unsigned NOT NULL,
`MaterialID` INT unsigned NOT NULL,
`Quantity` INT unsigned NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `Ingredients`
(`MaterialID`,`Material`,`MaterialImage`,`IsRecipe`)
VALUES
(1,'Redstone','redstone.jpg',0),
(2,'Iron Ingot','ironingot.jpg',0),
(3,'Wood Planks','woodplanks.jpg',0),
(4,'Stone','stone.jpg',0),
(5,'Slimeball','slimeball.jpg',0),
(6,'Piston','piston.jpg',1),
(7,'Sticky Piston','stickypiston.jpg',1),
(8,'Sticky Piston 2','stickypiston2.jpg',1);
INSERT INTO `Recipes_Ingredients`
(`RecipeID`,`MaterialID`,`Quantity`)
VALUES
(6,1,1),
(6,2,1),
(6,3,3),
(6,4,4),
(7,6,1),
(7,5,1),
(8,6,2),
(8,5,1);
Запрос 1 :
SELECT
a.`MaterialID`,
c.`MaterialID`,
a.`Material` as `Recipe`,
a.`MaterialImage` as `RecipeImage`,
c.`Material` as `Ingredient`,
b.`Quantity` as `FirstIngredientQuantity`,
c.`MaterialImage` as `IngredientImage`,
IF(d.`Quantity` IS NULL,SUM(b.`Quantity`),COALESCE(d.`Quantity`,0)*b.`Quantity`) as `Quantity`,
e.`Material` as `Ingredient`,
e.`MaterialImage` as `MaterialImage`
FROM `Ingredients` a
LEFT JOIN `Recipes_Ingredients` b
ON b.`RecipeID` = a.`MaterialID`
LEFT JOIN `Ingredients` c
ON c.`MaterialID` = b.`MaterialID`
LEFT JOIN `Recipes_Ingredients` d
ON d.`RecipeID` = c.`MaterialID`
LEFT JOIN `Ingredients` e
ON e.`MaterialID` = d.`MaterialID` AND c.`IsRecipe` = 1
WHERE a.`IsRecipe` = 1 AND a.`MaterialID` in (7,8)
GROUP BY a.`MaterialID`,c.`MaterialID`,e.`MaterialID`
Результаты
| MaterialID | MaterialID | Recipe | RecipeImage | Ingredient | FirstIngredientQuantity | IngredientImage | Quantity | Ingredient | MaterialImage |
|------------|------------|-----------------|-------------------|------------|-------------------------|-----------------|----------|-------------|----------------|
| 7 | 5 | Sticky Piston | stickypiston.jpg | Slimeball | 1 | slimeball.jpg | 1 | (null) | (null) |
| 7 | 6 | Sticky Piston | stickypiston.jpg | Piston | 1 | piston.jpg | 1 | Redstone | redstone.jpg |
| 7 | 6 | Sticky Piston | stickypiston.jpg | Piston | 1 | piston.jpg | 1 | Iron Ingot | ironingot.jpg |
| 7 | 6 | Sticky Piston | stickypiston.jpg | Piston | 1 | piston.jpg | 3 | Wood Planks | woodplanks.jpg |
| 7 | 6 | Sticky Piston | stickypiston.jpg | Piston | 1 | piston.jpg | 4 | Stone | stone.jpg |
| 8 | 5 | Sticky Piston 2 | stickypiston2.jpg | Slimeball | 1 | slimeball.jpg | 1 | (null) | (null) |
| 8 | 6 | Sticky Piston 2 | stickypiston2.jpg | Piston | 2 | piston.jpg | 2 | Redstone | redstone.jpg |
| 8 | 6 | Sticky Piston 2 | stickypiston2.jpg | Piston | 2 | piston.jpg | 2 | Iron Ingot | ironingot.jpg |
| 8 | 6 | Sticky Piston 2 | stickypiston2.jpg | Piston | 2 | piston.jpg | 6 | Wood Planks | woodplanks.jpg |
| 8 | 6 | Sticky Piston 2 | stickypiston2.jpg | Piston | 2 | piston.jpg | 8 | Stone | stone.jpg |
Запрос 2 :
SELECT
a.`MaterialID`,
c.`MaterialID`,
a.`Material` as `Recipe`,
a.`MaterialImage` as `RecipeImage`,
c.`Material` as `Ingredient`,
c.`MaterialImage` as `MaterialImage`,
SUM(b.`Quantity` + COALESCE(d.`Quantity`,0)) as `Quantity`,
COALESCE(GROUP_CONCAT(CONCAT(e.`Material`,' (',b.`Quantity` * d.`Quantity`,') [',e.`MaterialImage`,']')),'None') as `Ingredients`
FROM `Ingredients` a
LEFT JOIN `Recipes_Ingredients` b
ON b.`RecipeID` = a.`MaterialID`
LEFT JOIN `Ingredients` c
ON c.`MaterialID` = b.`MaterialID`
LEFT JOIN `Recipes_Ingredients` d
ON d.`RecipeID` = c.`MaterialID`
LEFT JOIN `Ingredients` e
ON e.`MaterialID` = d.`MaterialID` AND c.`IsRecipe` = 1
WHERE a.`IsRecipe` = 1
GROUP BY a.`MaterialID`,c.`MaterialID`
Результаты
| MaterialID | MaterialID | Recipe | RecipeImage | Ingredient | MaterialImage | Quantity | Ingredients |
|------------|------------|-----------------|-------------------|-------------|----------------|----------|-------------------------------------------------------------------------------------------------------------------|
| 6 | 1 | Piston | piston.jpg | Redstone | redstone.jpg | 1 | None |
| 6 | 2 | Piston | piston.jpg | Iron Ingot | ironingot.jpg | 1 | None |
| 6 | 3 | Piston | piston.jpg | Wood Planks | woodplanks.jpg | 3 | None |
| 6 | 4 | Piston | piston.jpg | Stone | stone.jpg | 4 | None |
| 7 | 5 | Sticky Piston | stickypiston.jpg | Slimeball | slimeball.jpg | 1 | None |
| 7 | 6 | Sticky Piston | stickypiston.jpg | Piston | piston.jpg | 13 | Redstone (1) [redstone.jpg],Iron Ingot (1) [ironingot.jpg],Wood Planks (3) [woodplanks.jpg],Stone (4) [stone.jpg] |
| 8 | 5 | Sticky Piston 2 | stickypiston2.jpg | Slimeball | slimeball.jpg | 1 | None |
| 8 | 6 | Sticky Piston 2 | stickypiston2.jpg | Piston | piston.jpg | 17 | Redstone (2) [redstone.jpg],Iron Ingot (2) [ironingot.jpg],Wood Planks (6) [woodplanks.jpg],Stone (8) [stone.jpg] |