Агрегировать функции только в одном столбце? - PullRequest
0 голосов
/ 15 октября 2018

Моя цель обучения: - найти, как найти ингредиент, и выяснить, какой рецепт использует тот или иной ингредиент.

Например,

+------------+--------------+--------+
| Pizza      | Ingredient   | Amount |
+------------+--------------+--------+
| Anchovy    | Anchovy      | 200    |
+------------+--------------+--------+
| Meatlovers | Pepparoni    | 150    |
+------------+--------------+--------+
| X pizza    | X ingredient | 50     |
+------------+--------------+--------+

Через:

(a) SELECT INGREDIENT,MAX(AMOUNT) FROM RECIPE GROUP BY INGREDIENT;

Прекрасно работает, однако я хочу знать название рецепта для пиццы.

(b) SELECT NAME,INGREDIENT,MAX(AMOUNT) FROM RECIPE GROUP BY INGREDIENT,NAME;

Не работает должным образом - я хочу, чтобы имя добавлялось в набор результатов (а) .Хотя я получаю пиццу, ингредиенты, максимальные количества.Я предполагаю, что функция max применяется и к столбцу пиццы, что мне не нужно.Есть ли способ указать агрегатную функцию, которая будет применяться только к двум нужным столбцам и оставить один (только для просмотра).

Ответы [ 3 ]

0 голосов
/ 15 октября 2018

PostgreSql поддерживает оконные функции , поэтому простой способ заключается в следующем:

SELECT  Pizza, 
        Ingredient,
        MAX(Amount) OVER(PARTITION BY Ingredient) As MaxAmount
FROM Recipe

Повторное чтение вопроса после комментария Дэмиена, я думаю, что то, что вы спрашиваете, не получит васрезультаты, которые вы хотите.

В начале вопроса вы написали:

Моя цель обучения: - найти, как найти ингредиент и увидетькакой рецепт использует любой данный ингредиент наиболее.посмотрите, какой рецепт использует тот или иной ингредиент.

Позже вы написали:

Я хочу, чтобы имя было добавлено к результирующему набору (a)

Эти утверждения противоречат.

Чтобы узнать, какая пицца использует больше всего определенного ингредиента, как вы указали в своем первом утверждении, используйте (б) запрос из вашего вопроса.Вы можете упорядочить результаты по ингредиентам, следуя столбцу MAX(AMOUNT) в порядке убывания - это позволит вам легко увидеть, какая пицца использует большинство ингредиентов.

SELECT Name, Ingredient, MAX(Amount) AS MaxAmount
FROM Recipe
GROUP BY Ingredient,Name
ORDER BY Ingredient, MaxAmount DESC;

Запрос вМой ответ, однако, даст вам то, что вы просите во втором утверждении - получить максимальное значение для каждого ингредиента, сгруппированное только по ингредиентам, но добавив название пиццы в набор результатов.(Другими словами - добавьте название пиццы к результирующему набору (a) )

0 голосов
/ 15 октября 2018

Стандартный современный подход к этому состоит в использовании оконной функции для назначения номеров строк:

SELECT
    *
FROM
    (SELECT
        *,
        ROW_NUMBER() OVER (PARTITION BY Ingredient ORDER BY Amount DESC) as rn
    FROM
       Recipe) r
where
    r.rn = 1

Это будет произвольно выбирать одну строку в качестве верхней строки, если их несколькоряды с тем же самым высоким Amount для конкретного ингредиента.Чтобы получить больше контроля над запросом, чтобы разорвать связи, добавьте другое выражение ORDER BY в предложении OVER.В качестве альтернативы, если вы хотите увидеть все связывающие строки, используйте RANK() вместо ROW_NUMBER().

0 голосов
/ 15 октября 2018

использовать связанный подзапрос

   SELECT r.* 
   FROM RECIPE AS r 
   where r.AMOUNT =
                 ( select MAX(AMOUNT)          
                  FROM RECIPE r1 where
                  r1.INGREDIENT=r.INGREDIENT
                  GROUP BY r1.INGREDIENT
                 ) 
...