Microsoft SQL 服务器计算连续事件之间的总时间
Microsoft SQL Server calculate total time between successive events
这里先post,但是谁能指导或者帮我理解下面的problem.For下面的table"Patient_Table",我怎么才能知道总的个数天 patient_id 22 病了。
ID Patient_ID Listing_Number Date Status
-----------------------------------------------------------------
1 22 1 01/01/2016 Healthy
2 22 2 01/11/2016 Sick
3 34 1 01/13/2016 Healthy
4 22 3 01/20/2016 Healthy
5 22 4 01/22/2016 Sick
6 22 5 01/23/2016 Healthy
以下是我到目前为止的逻辑,但我不确定语法是否正确。
declare
@count int = 1,
@Days_sicks int = 0
while @count <= (select max (Listing_number) from Patient_Table where Patient_id = '22')
begin
case
when (select status from Patient_Table where Patient_id = '22' and Listing_number = @count) = 'Sick'
then @Days_sicks = @Days_sicks + datediff('dd', (select min date from Patient_Table where patient_id = 22 and listing_number > @count and status != 'Sick'), (select date from patient_table where patient_id = 22 and listing_number = @count)
else @Days_sicks
end as Days_sicks
set @Count = @Count + 1
END;
我也试过这个,但效果不是很好,我对 group by 子句有疑问
SELECT t1.patient_id,
DATEDIFF(dd,
t1.date,
(SELECT MIN(t3.date)
FROM Patient_Table t3
WHERE t3.patient_id = t1.patient_id
AND t3.date> t1.date) as Days_sicks
)
FROM Patient_Table t1
WHERE EXISTS(
SELECT 'NEXT'
FROM Patient_Table t2
WHERE t2.patient_id = t1.patient_id
AND t2.date> t1.date
AND t2.status != 'sick')
and t1.patient_id = '22'
期望的结果
Patient id Days_sicks
22 10
使用lead()
函数然后聚合:
select patient_id,
sum(datediff(day, date, coalesce(next_date, getdate())))
from (select pt.*,
lead(date) over (partition by patient_id order by date) as next_date
from patient_table pt
) pt
where status = 'Sick'
group by patient_id;
注意:如果某人目前生病,则使用当前日期作为 "sick" 状态的结束日期。
此外,如果患者生病多次就诊,这将有效。
Select s.Patient_ID,
sum(datediff(day, s.Date, coalesce(h.date, getdate()) totalDaysSick
From table s left join table h
on h.Patient_ID = s.Patient_ID
and h.Status = 'Healthy'
and s.Status ='Sick'
and h.Date = (Select Min(date) from table
where Patient_ID = s.Patient_ID
and Date > s.Date)
Group By Patient_Id
您可以使用 Lag
窗口函数并按日期排序,然后执行 datediff 以查找当前日期和上一个日期之间的天数。然后对天数进行求和:
select
sickdays.Patient_ID
,Sum(sickdays.DayNums) as SickDays
from
(select
Patient_ID
,Datediff(day, Lag([Date], 1, null) over (order by [Date]), [Date]) as DayNums
from Patient
where Patient_ID = 22
and Status = 'Sick'
group by Patient_ID
,Date) as sickdays
where
sickdays.DayNums is not null
group by sickdays.Patient_ID
这里先post,但是谁能指导或者帮我理解下面的problem.For下面的table"Patient_Table",我怎么才能知道总的个数天 patient_id 22 病了。
ID Patient_ID Listing_Number Date Status
-----------------------------------------------------------------
1 22 1 01/01/2016 Healthy
2 22 2 01/11/2016 Sick
3 34 1 01/13/2016 Healthy
4 22 3 01/20/2016 Healthy
5 22 4 01/22/2016 Sick
6 22 5 01/23/2016 Healthy
以下是我到目前为止的逻辑,但我不确定语法是否正确。
declare
@count int = 1,
@Days_sicks int = 0
while @count <= (select max (Listing_number) from Patient_Table where Patient_id = '22')
begin
case
when (select status from Patient_Table where Patient_id = '22' and Listing_number = @count) = 'Sick'
then @Days_sicks = @Days_sicks + datediff('dd', (select min date from Patient_Table where patient_id = 22 and listing_number > @count and status != 'Sick'), (select date from patient_table where patient_id = 22 and listing_number = @count)
else @Days_sicks
end as Days_sicks
set @Count = @Count + 1
END;
我也试过这个,但效果不是很好,我对 group by 子句有疑问
SELECT t1.patient_id,
DATEDIFF(dd,
t1.date,
(SELECT MIN(t3.date)
FROM Patient_Table t3
WHERE t3.patient_id = t1.patient_id
AND t3.date> t1.date) as Days_sicks
)
FROM Patient_Table t1
WHERE EXISTS(
SELECT 'NEXT'
FROM Patient_Table t2
WHERE t2.patient_id = t1.patient_id
AND t2.date> t1.date
AND t2.status != 'sick')
and t1.patient_id = '22'
期望的结果
Patient id Days_sicks
22 10
使用lead()
函数然后聚合:
select patient_id,
sum(datediff(day, date, coalesce(next_date, getdate())))
from (select pt.*,
lead(date) over (partition by patient_id order by date) as next_date
from patient_table pt
) pt
where status = 'Sick'
group by patient_id;
注意:如果某人目前生病,则使用当前日期作为 "sick" 状态的结束日期。
此外,如果患者生病多次就诊,这将有效。
Select s.Patient_ID,
sum(datediff(day, s.Date, coalesce(h.date, getdate()) totalDaysSick
From table s left join table h
on h.Patient_ID = s.Patient_ID
and h.Status = 'Healthy'
and s.Status ='Sick'
and h.Date = (Select Min(date) from table
where Patient_ID = s.Patient_ID
and Date > s.Date)
Group By Patient_Id
您可以使用 Lag
窗口函数并按日期排序,然后执行 datediff 以查找当前日期和上一个日期之间的天数。然后对天数进行求和:
select
sickdays.Patient_ID
,Sum(sickdays.DayNums) as SickDays
from
(select
Patient_ID
,Datediff(day, Lag([Date], 1, null) over (order by [Date]), [Date]) as DayNums
from Patient
where Patient_ID = 22
and Status = 'Sick'
group by Patient_ID
,Date) as sickdays
where
sickdays.DayNums is not null
group by sickdays.Patient_ID