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