Select group by 上每组的最大记录数

Select max record of each group on a group by

我正在使用 PostgreSQL。 我需要select每个组的max,情况是table代表每天销售的产品,我想知道销量最高的每天的产品。

SELECT sum(detalle_orden.cantidad) as suma,detalle_orden.producto_id as producto
      ,to_char(date_trunc('day',orden.fecha AT TIME ZONE 'MST'),'DY') as dia
FROM detalle_orden
LEFT JOIN orden ON orden.id = detalle_orden.order_id
GROUP BY orden.fecha,detalle_orden.producto_id 
ORDER BY dia,suma desc

正在返回:

suma  producto  dia
4     1         FRI
1     2         FRI
5     3         TUE
2     2         TUE

我想得到:

suma  producto  dia
4     1         FRI
5     3         TUE

只有每天的顶级产品(每个组的max(suma))。

我尝试了不同的方法,比如子查询,但是使用的聚合函数让事情变得有点困难。

您可以(滥用)使用带有适当排序子句的 SELECT DISTINCT ON。假设您将之前的查询放入视图中:

SELECT DISTINCT ON (dia, producto) * FROM some_view ORDER BY dia, producto, suma DESC;

DISTINCT 确保您只会为每一天和产品保留一行,ORDER BY 确保它保留正确的一行

通过窗口函数:RANK 可以轻松搞定:

select * from
(
select suma,producto,dia, rank() over (partition by dia order by suma desc) as ranking
from your_query
)A
where ranking = 1

所以你最终的查询将是这样的:

select * from
(
select suma,producto,dia, rank() over (partition by dia order by suma desc) as ranking
from 
(
SELECT sum(detalle_orden.cantidad) as suma,detalle_orden.producto_id as     producto,to_char(date_trunc
    ('day',orden.fecha AT TIME ZONE 'MST'),'DY') as dia FROM detalle_orden     LEFT JOIN
    orden ON orden.id= detalle_orden.order_id GROUP by
    orden.fecha,detalle_orden.producto_id ) B
) A
where ranking = 1

您仍然可以使用 DISTINCT ON 在没有子查询的单个查询级别中完成此操作,因为 DISTINCTGROUP BY 和聚合函数之后(以及在 window 函数):

SELECT DISTINCT ON (3)
       sum(d.cantidad) AS suma
     , d.producto_id AS producto
     , to_char(o.fecha AT TIME ZONE 'MST', 'DY') AS dia
FROM   detalle_orden d
LEFT   JOIN orden o ON o.id = d.order_id
GROUP  BY o.fecha, d.producto_id 
ORDER  BY 3, 1 DESC NULLS LAST, d.producto_id;

备注

  • 此解决方案 returns 每个 dia 正好一个 行(如果可用) .如果多个产品并列最高销售额,我的任意(但确定性和可重复性)选择是具有较小 producto_id.
    的那个 如果您需要所有同龄人并列一天,请按照@Houari 的建议使用 rank()

  • SQLSELECT 查询中的事件序列在这个相关答案中有解释:

    • Best way to get result count before LIMIT was applied
  • date_trunc() 只是 dia 计算中的噪音。我删除了它。

  • 我将 NULLS LAST 添加到降序排序中,因为不清楚结果中是否存在 suma 为 NULL 的行:

    • PostgreSQL sort by datetime asc, null first?
  • DISTINCT ONGROUP BY中的数字只是为了方便起见的语法符号shorthand。类似:

    • PostgreSQL equivalent for MySQL GROUP BY

    与添加的 table 别名一样(语法 shorthand 符号)。

  • DISTINCT ON

    的基础知识
    • Select first row in each GROUP BY group?