关于sql:仅获取“上个月”的平均值

Get average for “last month” only

对SQL来说很新,并且遇到了障碍。

我有这个查询,工作正常:

1
2
3
SELECT
(COUNT(*)::FLOAT / (CURRENT_DATE - '2017-05-17'::DATE)) AS"avg_per_day"
FROM"table" tb;

我现在希望它只包含上个月的数据,而不是所有时间。

我尝试过以下方面的做法:

1
2
3
SELECT
(COUNT(*)::FLOAT / (CURRENT_DATE - (CURRENT_DATE - '1 month' ::DATE)) AS"avg_per_day"
FROM"table" tb;

语法显然是错误的,但我不确定正确的答案是什么。 谷歌搜索各种选项无济于事。

我不能使用简单的AVG,因为我需要的数字是上个月数据每天的AVG。 因此,我已经完成了行数除以自第一次出现以来每天获得AVG的天数。

我有一个列告诉我发生的日期,但是数据集中有多个行具有相同的日期。 例如

1
2
3
4
5
created_at
----------------------------
Monday 27th June 2017 12:00
Monday 27th June 2017 13:00
Tuesday 28th June 2017 12:00

等等。

我计算每天发生的次数,然后需要计算出平均值,仅为结果的最后一个月(它们可以追溯到5月)。


答案取决于"上个月"的确切定义以及"平均数"的确切定义。

假设:

  • 您的列已定义created_at timestamptz NOT NULL
  • 您希望每天的平均行数 - 没有任何行的天数计为0。
  • 完全覆盖30天,不包括今天。
1
2
3
4
SELECT round(COUNT(*)::NUMERIC / 30, 2)  -- simple now with a fixed number of days
FROM   tbl
WHERE  created_at >= (now()::DATE - 30)
AND    created_at <   now()::DATE        -- excl. today

舍入是可选的,但您需要numeric而不是float才能以这种方式使用round()

不包括当前日期("今天"),这一天正在进行,可能导致较低的误导性平均值。

如果"上个月"应该意味着别的东西,你需要准确地定义它。月份有28到31天,这可能意味着各种各样的事情。而且,由于您显然使用timestamptimestamptz而不是date进行操作,因此您还需要了解一天中的时间和当前时区的可能影响。转换为date(或一般的"日期"的定义)取决于使用timestamptz操作时的当前timezone设置。

有关:

  • 在Rails和PostgreSQL中完全忽略时区
  • 仅选择今天(从午夜开始)时间戳
  • 从now()函数中减去小时数


我想你只需要一个where子句:

1
2
3
4
SELECT
(COUNT(*)::FLOAT / (CURRENT_DATE - (CURRENT_DATE - '1 month' ::DATE)) AS"avg_per_day"
FROM"table" tb
WHERE created_at > (CURRENT_DATE - '1 month' ::DATE)


我相信Postgresql和其他RDBMS有AVG()来计算平均值。

1
2
3
4
5
SELECT AVG(tb.columnName) AS avg_per_month
FROM someTable tb
WHERE  
 tb.createdDate >= [START DATE OF MONTH] AND
 tb.createdDate <= [END DATE OF MONTH]

编辑:我用INTERVAL减去当前日期。我在手机上,所以我无法测试。

1
2
3
SELECT
(COUNT(*)::FLOAT / (CURRENT_DATE -  ( CURRENT_DATE -  INTERVAL '1 month')) AS"avg_per_day"
FROM"table" tb;