仅在单个列上汇总函数吗?

时间:2018-10-15 06:18:25

标签: sql postgresql greatest-n-per-group

我的学习目标:是找到如何找到一种成分并查看哪种食谱使用给定成分的次数最多。

例如

+------------+--------------+--------+
| 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;

不能按预期方式工作-我希望将该名称附加到结果集(a)。虽然,我得到的是所有比萨,配料,最大量。我假设max函数也将自身应用到披萨列,这是我不想要的。有没有一种方法可以指定仅应用于两个所需列的聚合函数,并保留一个(仅用于查看目的)。

3 个答案:

答案 0 :(得分:1)

PostgreSql支持window functions,所以简单的方法是这样:

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

根据达米安(Damien)的评论,再次阅读问题,我认为您要问的内容不会为您带来想要的结果。

在问题的开头,您写道:

  

我的学习目标:是找到如何找到一种成分,并查看哪种食谱使用给定成分的次数最多。看看哪种食谱使用任何给定的成分最多。

您后来写过:

  

我希望将名称添加到(a)

的结果集中

这些语句冲突。

要像您在第一句话中所说的那样,要知道哪个比萨饼使用了最多的特定成分,请使用问题中的(b)查询。您可以按MAX(AMOUNT)列的降序按成分对结果进行排序-这将使您轻松查看比萨饼中每种成分的使用量最多。

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

但是,我的答案中的查询将使您获得在第二条语句中要问的内容-获得每种成分的最大值,仅按成分分组,但将比萨名称添加到结果集中。 (换句话说,将比萨饼名称附加到结果集(a)

答案 1 :(得分:1)

一种标准的现代方法是使用window function分配行号:

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()

答案 2 :(得分:0)

使用相关子查询

%