[英]PostgreSQL count of each status per day
我有下表:
Reservations
| id | status | created_at |
| 1 | Opened | 2019-11-12 11:46:11 |
| 1 | Completed | 2019-11-19 23:03:24 |
| 1 | Pending | 2019-11-15 12:04:13 |
| 2 | Opened | 2019-11-14 11:46:11 |
| 2 | Completed | 2019-11-20 23:03:24 |
| 2 | Pending | 2019-11-17 12:04:13 |
从 2019 年 11 月 1 日到 2019 年 12 月 31 日,每个日历日我都有一张桌子。
我需要找出在上面列出的时间跨度内每个日历日存在的每种状态的出现次数。
如果状态是在2019年12月14日和待定的2019年12月17日开业,我需要计算,它被打开每天从2019年12月14日至2019年12月17日。
理想的:
|2019-11-12 00:00:00 | Opened | 1 |
|2019-11-12 00:00:00 | Pending | 0 |
|2019-11-12 00:00:00 | Completed | 0 |
|2019-11-13 00:00:00 | Opened | 1 |
|2019-11-13 00:00:00 | Pending | 0 |
|2019-11-13 00:00:00 | Completed | 0 |
|2019-11-14 00:00:00 | Opened | 2 |
|2019-11-14 00:00:00 | Pending | 0 |
|2019-11-14 00:00:00 | Completed | 0 |
|2019-11-15 00:00:00 | Opened | 1 |
|2019-11-15 00:00:00 | Pending | 1 |
|2019-11-15 00:00:00 | Completed | 0 |
任何帮助是极大的赞赏。
编辑:下面来自 GMB 的解决方案非常接近,但它给我留下了下表:
| status | created_at | ended_at |
| Opened | 2019-11-12 11:46:11 | 2019-11-15 12:04:13 |
| Pending | 2019-11-15 12:04:13 | 2019-11-19 23:03:24 |
| Completed | 2019-11-19 23:03:24 | |
| Opened | 2019-11-14 11:46:11 | 2019-11-17 12:04:13 |
| Pending | 2019-11-17 12:04:13 | 2019-11-20 23:03:24 |
| Completed | 2019-11-20 23:03:24 | |
如何将结束日期添加到我的范围 (2019-12-31) 到缺失的列值?
我会这样做:获取每个 ID 的每个状态的开始和结束,使用您的表计算从 2019-11-01 到 2019-12-31 的每个日历日的发生次数,并按状态和日期进行基本计数
with Reservations cte as
(
select
a.id, a.status, a.created_at::date,
LAG(a.created_at::date, 1,0) OVER (PARTITION BY YEAR(a.id) ORDER BY YEAR(a.created_at))
AS Ended_at
Reservations a
)
Select b.day, status, count(*)
from Reservations a inner join calendar b on b.day >= created_at and
b.day < Ended_at
group by b.day, status
考虑以下查询:
select
c.dt,
s.status,
count(t.status)
from
calendar c
cross join (select distinct status from reservations) s
left join (
select
status,
created_at,
lead(created_at) over(partition by id order by created_at) ended_at
from reservations
) t
on t.status = s.status
and c.dt + interval '1 day' >= t.created_at
and c.dt + interval '1 day' < t.ended_at
group by c.dt, s.status
order by c.dt, s.status
这是通过将日历表与表中可用的不同状态列表交叉连接,然后将其与使用lead()
的子查询连接来获得与每条记录关联的下一个状态的日期来实现的。 如果您有状态表,则可以使用它代替选择不同状态的子查询。
dt | status | count :--------------------- | :-------- | ----: 2019-11-12 00:00:00+00 | Completed | 0 2019-11-12 00:00:00+00 | Opened | 1 2019-11-12 00:00:00+00 | Pending | 0 2019-11-13 00:00:00+00 | Completed | 0 2019-11-13 00:00:00+00 | Opened | 1 2019-11-13 00:00:00+00 | Pending | 0 2019-11-14 00:00:00+00 | Completed | 0 2019-11-14 00:00:00+00 | Opened | 2 2019-11-14 00:00:00+00 | Pending | 0 2019-11-15 00:00:00+00 | Completed | 0 2019-11-15 00:00:00+00 | Opened | 1 2019-11-15 00:00:00+00 | Pending | 1
请注意,DB Fiddle 演示了如何使用方便的 Postgres 函数generate_series()
来填充日历表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.