如何在SQL Server 17中从住院患者表筛选30天内再入院病例并计算其总住院时长(LOS)
SQL Server 17: Calculate Total LOS for Patient Admission Groups (30-Day Readmission Logic)
First, let's recap your data and desired output for clarity:
Original Admission Data
| ID | AdmissionDate | DischDate | LOS | Readmitted30days |
|---|---|---|---|---|
| 001 | 2014-01-01 | 2014-01-12 | 11 | 1 |
| 101 | 2014-02-05 | 2014-02-12 | 7 | 1 |
| 001 | 2014-02-18 | 2014-02-27 | 9 | 1 |
| 001 | 2018-02-01 | 2018-02-13 | 12 | 0 |
| 212 | 2014-01-28 | 2014-02-12 | 15 | 1 |
| 212 | 2014-03-02 | 2014-03-15 | 13 | 0 |
| 212 | 2016-12-23 | 2016-12-29 | 4 | 0 |
| 1011 | 2017-06-10 | 2017-06-21 | 11 | 0 |
| 401 | 2018-01-01 | 2018-01-11 | 10 | 0 |
| 401 | 2018-10-01 | 2018-10-10 | 9 | 0 |
Desired Output
| ID | Total LOS |
|---|---|
| 001 | 39 |
| 212 | 28 |
| 212 | 4 |
| 1011 | 11 |
| 401 | 10 |
| 401 | 9 |
Solution Query
The core idea is to group admissions for the same patient that are within a 30-day window of each other, then sum their LOS values. We'll use window functions to identify these groups:
-- Replace YourTableName with the actual name of your table WITH RankedAdmissions AS ( SELECT ID, AdmissionDate, DischDate, LOS, -- Calculate days between current admission and previous discharge DATEDIFF(day, LAG(DischDate) OVER (PARTITION BY ID ORDER BY AdmissionDate), AdmissionDate) AS DaysSinceLastDischarge, -- Flag if this admission starts a new group (first admission or >30 days since last discharge) CASE WHEN LAG(DischDate) OVER (PARTITION BY ID ORDER BY AdmissionDate) IS NULL THEN 1 WHEN DATEDIFF(day, LAG(DischDate) OVER (PARTITION BY ID ORDER BY AdmissionDate), AdmissionDate) > 30 THEN 1 ELSE 0 END AS IsNewGroup FROM YourTableName ), GroupedAdmissions AS ( SELECT ID, LOS, -- Generate a unique group ID for each cluster of admissions SUM(IsNewGroup) OVER (PARTITION BY ID ORDER BY AdmissionDate ROWS UNBOUNDED PRECEDING) AS GroupID FROM RankedAdmissions ) SELECT ID, SUM(LOS) AS [Total LOS] FROM GroupedAdmissions GROUP BY ID, GroupID ORDER BY ID, GroupID;
How This Works
RankedAdmissions CTE:
- We partition the data by
IDand sort admissions byAdmissionDateto process each patient's records in chronological order. LAG(DischDate)fetches the discharge date of the patient's previous admission, and we calculate the gap between that date and the current admission usingDATEDIFF.- We set
IsNewGroupto 1 if this is the patient's first admission, or if more than 30 days have passed since their last discharge (signaling a separate, unrelated admission episode).
- We partition the data by
GroupedAdmissions CTE:
- We use a running total of
IsNewGroupto assign a uniqueGroupIDto each cluster of admissions that fall within 30 days of each other. Each timeIsNewGroupis 1, the group ID increments, creating a new cluster.
- We use a running total of
Final Aggregation:
- We group by
IDandGroupID, then sum theLOSvalues to get the total length of stay for each admission cluster.
- We group by
This logic matches your desired output: for example, patient 212's first two admissions are only 18 days apart (from discharge to next admission), so they're grouped together for a total LOS of 28. Their 2016 admission is far enough from the previous one to be its own group with a total LOS of 4.
内容的提问来源于stack exchange,提问作者Mel
相关产品推荐
相关产品推荐

