PostgreSQL 结合计数、最近 7 天计数和最近 30 天计数 按天分组

Mat*_*att 4 sql postgresql datetime count date-arithmetic

我有一个小表 ( TABLEA),其中有两列IDA& DATETIMEA

塔贝拉

IDA  DATETIMEA
1    2020-03-16 13:15:00
2    2020-03-17 15:25:00
3    2020-03-18 17:10:00
5    2020-03-19 11:44:00
5    2020-03-20 12:55:00
5    2020-03-21 19:35:00
7    2020-03-22 10:13:00
8    2020-03-22 15:25:00
8    2020-03-28 12:12:00
9    2020-03-29 17:55:00
10   2020-03-30 11:54:00
12   2020-03-30 15:35:00
12   2020-03-31 13:19:00
Run Code Online (Sandbox Code Playgroud)

我正在尝试获取IDA每天的总计、过去 7 天的总计和过去 30 天的总计。

预期输出

DATE       DAY L7 L30
2020-03-16 1   1  1
2020-03-17 1   2  2
2020-03-18 1   3  3
2020-03-19 1   4  4
2020-03-20 1   5  5
2020-03-21 1   6  6
2020-03-22 2   8  8  
2020-03-28 1   3  9
2020-03-29 1   4  10
2020-03-30 2   6  12
2020-03-31 1   7  13
Run Code Online (Sandbox Code Playgroud)

我尝试将与日期相关的输出放入子查询中,但它们返回 0。

SELECT t.DATETIMEA::date date,
COUNT(t.*) "day",
(SELECT COUNT(w.*) FROM TABLEA w WHERE w.DATETIMEA::date BETWEEN w.DATETIMEA::date AND w.DATETIMEA::date - 7) week,
(SELECT COUNT(m.*) FROM TABLEA m WHERE m.DATETIMEA::date BETWEEN m.DATETIMEA::date AND m.DATETIMEA::date - 30) "month"
FROM TABLEA t
GROUP BY t.DATETIMEA::date
ORDER BY t.DATETIMEA::date
Run Code Online (Sandbox Code Playgroud)

GMB*_*GMB 6

如果您的数据可能存在几天的间隙,那么您需要一个range框架规范而不是一个rows框架。幸运的是 Postgres 支持这个规范,所以你可以这样做:

select
    datetimea::date date,
    count(*) "day",
    sum(count(*)) over(
        order by datetimea::date
        range between '7 day' preceding and current row
    ) l7,
        sum(count(*)) over(
        order by datetimea::date
        range between '30 day' preceding and current row
    ) l30
from mytable
group by datetimea::date
order by datetimea::date 
Run Code Online (Sandbox Code Playgroud)

DB Fiddle 演示

日期 | 日 | l7 | l30
:--------- | --: | -: | --:
2020-03-16 | 1 | 1 | 1
2020-03-17 | 1 | 2 | 2
2020-03-18 | 1 | 3 | 3
2020-03-19 | 1 | 4 | 4
2020-03-20 | 1 | 5 | 5
2020-03-21 | 1 | 6 | 6
2020-03-22 | 2 | 8 | 8
2020-03-28 | 1 | 4 | 9
2020-03-29 | 1 | 4 | 10
2020-03-30 | 2 | 4 | 12
2020-03-31 | 1 | 5 | 13