[英]SQL : calculate the number of days between date range on a history table
我有一个Person
表,其中有一个Status
列,反映了该人任务的当前状态。
PersonId Status
--------------------------------------------
1 In Progress
2 In Progress
3 Completed
4 In Progress
我还有一个PersonStatusHistory
表,其中包含一个LoggedDate
列以指示每个Person
的状态更改何时发生。
PersonId Status LoggedDate
--------------------------------------------
1 Created 11/11/2022
1 In Progress 11/15/2022
2 Created 11/05/2022
2 In Progress 11/07/2022
2 Blocked 11/10/2022
2 In Progress 11/15/2022
3 Created 11/03/2022
3 In Progress 11/12/2022
3 Completed 11/17/2022
4 Created 11/01/2022
4 In Progress 11/03/2022
4 Blocked 11/05/2022
4 In Progress 11/10/2022
4 Blocked 11/12/2022
4 In Progress 11/15/2022
我想获取当前状态 = In Progress 的所有 Person 记录,它处于In Progress
的天数减去它们被Blocked
的天数。
预期结果应如下所示:
Emp Id No of Days In Progress
--------------------------------------------
1 4
> 11/18 (date today) - 11/15 (first In Progress LoggedDate)
> 18 - 15 + 1 (current day) = 4 days
2 7
> 11/18 (date today) minus 11/07 (first In Progress LoggedDate)
> less the number of Blocked days
> 18 - 7 - 5 + 1 (current day) = 7
4 8 days
> 11/18 (date today) minus 11/03 (first In Progress LoggedDate)
> less the number of Blocked days (5 and 3 days)
> 18 - 3 - 5 - 3 + 1 (current day) = 8
我可以很容易地获得前 2 个所需的结果,但我很难弄清楚如何处理最后一个多次被阻止的用例。 到目前为止,这是我的代码
SELECT x.PersonId
, (DATE_PART('day', CURRENT_DATE + 1) - DATE_PART('day', x.start_in_progress_date)
- DATE_PART('day', end_blocked_date) - DATE_PART('day', x.start_blocked_date)
) as no_of_days_in_progress
FROM
(
SELECT p.PersonId
, MIN (psh.LoggedDate) AS start_in_progress_date
, (SELECT MIN(psh.LoggedDate)
FROM PersonStatusHistory psh2
WHERE psh2.PersonId = p.PersonId
AND psh2.Status = 'Blocked'
) as start_blocked_date
, (SELECT MAX(psh.LoggedDate)
FROM PersonStatusHistory psh3
WHERE psh3.PersonId = p.PersonId
AND psh3.Status = 'In Progress'
) as end_blocked_date
FROM Person p
INNER JOIN PersonStatusHistory psh
ON psh.PersonId = p.PersonId
WHERE p.Status = 'In Progress'
GROUP BY p.PersonId
) x
我认为更好的方法是让状态更改事件结束(通过 LEAD)并仅总结“进行中”状态持续时间
select personid, status, sum(event_duration) + 1
from (
SELECT personid, status , LoggedDate event_start,
coalesce (lead(LoggedDate,1) OVER( partition by personid ORDER BY LoggedDate),
current_date) - LoggedDate event_duration,
coalesce (lead(LoggedDate,1) OVER( partition by personid ORDER BY LoggedDate), current_date) as event_end
from personstatushistory p
order by 1,3 ) q
where status = 'In Progress'
group by personid, status
order by 1,2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.