Sequel Pro Combine Несколько строк, где только 1 столбец отличается, но остальные одинаковы

У меня есть столик для еды, и есть несколько идентификаторов, связанных с другими столами на главном столе.

У меня есть другая таблица, где ингредиенты для еды перечислены по идентификаторам, чтобы мне не приходилось набирать ингредиенты снова и снова. Но когда я запускаю следующий поиск, я получаю название еды, указанное несколько раз, потому что каждый ингредиент указан в отдельной строке. Как я могу заставить его отображать название, а затем все ингредиенты в одной строке?

SELECT
    mealName, ingredient, quantity 
FROM 
    meals, mealTotal, ingredients 
WHERE 
        mealTotal.mealId = meals.MealId 
    and mealTotal.ingredientId =  ingredients.ingredientId  
ORDER BY 
    mealName;

в настоящее время показывает:

Apple Pie    Apple    1
Apple Pie    Tabantha Wheat    1
Apple Pie    Goat Butter       1
Apple Pie    Cane Sugar    1

Что я хочу это показать:

Apple Pie    Apple   1    Tabantha Wheat    1      Goat Butter    1    Cane Sugar    1

1 ответ

Ты можешь использовать GROUP_CONCAT вернуть все ингредиенты и количества в виде списка. Итак, начиная с уже существующего запроса, вы должны преобразовать его в:

-- Concatenate all your (ingredient, quantity)
SELECT
    mealName, 
    GROUP_CONCAT(ingredient_and_quantity ORDER BY ingredient_and_quantity SEPARATOR '\t' ) AS ingredient_list
FROM
    (SELECT
        mealName, ingredient, quantity, 
        CONCAT(ingredient, ' ', quantity) AS ingredient_and_quantity
    FROM 
        meals
        JOIN mealTotal ON mealTotal.mealId = meals.mealId
        JOIN ingredients ON ingredients.ingredientId = mealTotal.ingredientId 
    ) AS q
ORDER BY 
    mealName;

Это даст вам строку со всеми ингредиентами и соответствующими количествами.

foodName  | ingredient_list:-------- |:-----------------------------------------------------------------------
Яблочный пирог | Яблоко 1 тростниковый сахар 1 козье масло 1 пшеница табанта 1

Обратите внимание, что я изменил вашу неявную JOIN с явными. (неявный JOIN Их сложнее читать и подвержены ошибкам, просто пропустить одно условие ссылки на WHERE и вы получите картезианский продукт, который вы не ожидали).

Вы можете проверить все это на dbfiddle здесь


Если вы хотите, чтобы список ингредиентов в разных столбцах (ingredient_1, quantity_1, ingredient_2, quantity_2, ...), затем вы можете начать с варианта этого запроса и разложить сгруппированные данные, используя SUBSTRING_INDEX(str,delim,count):

-- Pivot 
SELECT
    mealName, 
    SUBSTRING_INDEX(SUBSTRING_INDEX(ingredients, ',',  1), ',', -1) AS ingredient_1,
    SUBSTRING_INDEX(SUBSTRING_INDEX(ingredients, ',',  2), ',', -1) AS ingredient_2,
    SUBSTRING_INDEX(SUBSTRING_INDEX(ingredients, ',',  3), ',', -1) AS ingredient_3,
    SUBSTRING_INDEX(SUBSTRING_INDEX(ingredients, ',',  4), ',', -1) AS ingredient_4,

    SUBSTRING_INDEX(SUBSTRING_INDEX(quantities, ',',  1), ',', -1) AS quantity_1,
    SUBSTRING_INDEX(SUBSTRING_INDEX(quantities, ',',  2), ',', -1) AS quantity_2,
    SUBSTRING_INDEX(SUBSTRING_INDEX(quantities, ',',  3), ',', -1) AS quantity_3,
    SUBSTRING_INDEX(SUBSTRING_INDEX(quantities, ',',  4), ',', -1) AS quantity_4
FROM
    (SELECT
        mealName, 
        GROUP_CONCAT(ingredient ORDER BY ingredient SEPARATOR ',') AS ingredients,
        GROUP_CONCAT(quantity ORDER BY ingredient SEPARATOR ',') AS quantities
    FROM
        (SELECT
            mealName, ingredient, quantity
        FROM 
            meals
            JOIN mealTotal ON mealTotal.mealId = meals.mealId
            JOIN ingredients ON ingredients.ingredientId = mealTotal.ingredientId 
        ORDER BY
            mealName, ingredient
        ) AS q
    ) AS q2
ORDER BY 
    mealName;

Это даст вам что-то вроде:

foodName | ингредиент_1 | ингредиент_2 | ингредиент_3 | ингредиент_4   | количество_1 | количество_2 | количество_3 | quantity_4:-------- |:----------- |:----------- |:----------- |:------------- |:--------- |:--------- |:--------- | ---------
Яблочный пирог | Яблоко | Тростниковый сахар | Козье масло | Табанта Пшеница | 1.01       | 1,04       | 1,03       | 1,02      

Вы можете проверить это на dbfiddle здесь

Обратите внимание, что это не масштабируется (если вам нужно 10 столбцов, вам придется делать это вручную), и что некоторые значения могут повторяться из-за способа STRING_INDEX работает. Я бы не рекомендовал такой подход.

Другие вопросы по тегам