PostgreSQL 结合计数、最近 7 天计数和最近 30 天计数 按天分组
PostgreSQL combining a count, a last 7 days count and a last 30 days count Grouped by days
我有一个小的 table (TABLEA
),它有两列 IDA
和 DATETIMEA
。
TABLEA
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
我正在尝试获取每天 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
我试过将与日期相关的输出放在子查询中,但它们 return 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
我认为 window 函数可以满足您的需求:
select t.datetimea::date, count(*) as on_day,
sum(count(*)) over (order by t.datetimea::date rows between 6 preceding and current row) as sum_7,
sum(count(*)) over (order by t.datetimea::date rows between 29 preceding and current row) as sum_30
from tablea t
group by t.datetimea::date;
"last 7 days",我假设你指的是今天和之前的 6 天。如果你指的是今天之前的7天,window框架可以很容易地调整。
如果您的数据可能有几天的间隔,那么您需要 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
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 | 4 | 9
2020-03-29 | 1 | 4 | 10
2020-03-30 | 2 | 4 | 12
2020-03-31 | 1 | 5 | 13
我有一个小的 table (TABLEA
),它有两列 IDA
和 DATETIMEA
。
TABLEA
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
我正在尝试获取每天 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
我试过将与日期相关的输出放在子查询中,但它们 return 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
我认为 window 函数可以满足您的需求:
select t.datetimea::date, count(*) as on_day,
sum(count(*)) over (order by t.datetimea::date rows between 6 preceding and current row) as sum_7,
sum(count(*)) over (order by t.datetimea::date rows between 29 preceding and current row) as sum_30
from tablea t
group by t.datetimea::date;
"last 7 days",我假设你指的是今天和之前的 6 天。如果你指的是今天之前的7天,window框架可以很容易地调整。
如果您的数据可能有几天的间隔,那么您需要 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
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 | 4 | 9 2020-03-29 | 1 | 4 | 10 2020-03-30 | 2 | 4 | 12 2020-03-31 | 1 | 5 | 13