在 Postgres 中,如何平均每个用户的最新 5 个分数?

Posted

技术标签:

【中文标题】在 Postgres 中,如何平均每个用户的最新 5 个分数?【英文标题】:In Postgres, how can I average the latest 5 scores per user? 【发布时间】:2013-11-11 09:21:53 【问题描述】:

我被困在 Postgres 中的一个查询上,并且非常沮丧。我有一个名为 scores 的表,包含三列:

score, user_id and date

我想获得所有用户最近 5 分的平均值。这个查询并不完全让我明白:

SELECT user_id, 
       ROUND( AVG( score )::numeric, 2) as sc_avg
FROM 
(SELECT ROW_NUMBER() OVER (PARTITION BY user_id) AS r,
    sc.*
    from mg.scores sc
WHERE score IS NOT NULL
ORDER BY date DESC) AS x
WHERE x.r >= 5
GROUP BY user_id;

有没有更好的方法来限制每个用户的最后 5 个作业?

【问题讨论】:

您需要将ORDER BY date DESC 添加到over() 子句中,否则row_number() 不会返回您的想法(顺便说一句:date可怕的 列名) 【参考方案1】:

正如 a_horse 所说,ORDER BY 子句必须进入窗口函数。 由于您的订单是降序,它需要是而不是>=

SELECT user_id, round(avg(score)::numeric, 2) AS sc_avg
FROM  (
   SELECT *
        , row_number() OVER (PARTITION BY user_id ORDER BY date DESC) AS rn
   FROM   mg.scores
   WHERE  score IS NOT NULL
   ) AS x
WHERE  x.rn <= 5
GROUP  BY user_id;

如果date 可以是NULL,请使用ORDER BY date DESC NULLS LAST。见:

PostgreSQL sort by datetime asc, null first?

【讨论】:

以上是关于在 Postgres 中,如何平均每个用户的最新 5 个分数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Postgres 中获取时间间隔的平均值

Postgres 移动平均线

如何计算postgres的指数移动平均线?

优化 GROUP BY 查询以检索每个用户的最新行

如何在 SQL 中计算每个用户的唯一日期的平均收入

如何平均单个 PostGIS 栅格表中的所有波段?