SQL:选择最后一小时和最后一天的列平均值

时间:2019-02-24 11:28:41

标签: sql postgresql

我有一张类似下图的表格。我需要获取average列的Volume值,并按User 分别在1小时和24小时前分组单一查询中如何在两个不同的日期范围内使用avg
enter image description here

3 个答案:

答案 0 :(得分:2)

使用条件聚合。 Postgres使用FILTER子句提供了非常方便的语法:

SELECT user,
       AVG(Volume) FILTER (WHERE created >= NOW() - interval '1 hour' AND created <= NOW()) as avg_1hour,
       AVG(Volume) FILTER (WHERE created >= NOW() - interval '1 day' AND created <= NOW()) as avg_1day
FROM mytable
WHERE created >= NOW() - interval '1 DAY' AND
      created <= NOW()
GROUP BY user;

这将过滤掉过去一天没有活动的用户。如果要所有个用户(即使是那些近期没有活动的用户),请删除WHERE子句。

更传统的方法使用CASE

SELECT user,
       AVG(CASE WHEN created >= NOW() - interval '1 hour' AND created <= NOW() THEN Volume END) as avg_1hour,
       AVG(CASE WHEN created >= NOW() - interval '1 day' AND created <= NOW() THEN Volume END) as avg_1day
. . .

答案 1 :(得分:1)

您可以这样做:

SELECT user, AVG(Volume)
FROM mytable
WHERE created >= NOW() - interval '1 hour'
AND   created <= NOW()
GROUP BY user

没有什么要记住的,您正在同一时区的同一服务器上执行查询。您需要按用户分组以将卷列中的所有值分组,然后应用诸如avg之类的聚合函数来找到平均值。同样,如果同时需要两者,则可以执行以下操作:

SELECT u1.user, u1.average, u2.average
FROM
    (SELECT user, AVG(Volume) as average
    FROM mytable
    WHERE created >= NOW() - interval '1 hour'
    AND   created <= NOW()
    GROUP BY user) AS u1
INNER JOIN
    (SELECT user, AVG(Volume) as average
    FROM mytable
    WHERE created >= NOW() - interval '1 day'
    AND   created <= NOW()
    GROUP BY user) AS u2
ON u1.user = u2.user

答案 2 :(得分:0)

SELECT User, AVG(Volume) , ( IIF(created < DATE_SUB(NOW(), INTERVAL 1 HOUR) , 1 , 0) )IntervalType
WHERE created < DATE_SUB(NOW(), INTERVAL 1 HOUR)
      AND created < DATE_SUB(NOW(), INTERVAL 24 HOUR)
GROUP BY User, (IIF(created < DATE_SUB(NOW(), INTERVAL 1 HOUR))

请告诉我它的结果:)