标识记录的最新状态以及上次更改的时间

时间:2019-07-01 17:54:08

标签: sql-server group-by

感谢您提供机会解释我的问题。 我有一张表格,其中记录了所有入院患者的最新状况。 (带有示例数据的表结构如下)。要求是,应显示每个患者的最新状态以及最新状态出现的时间。

 ID | PatientId |       Status       |       TimeOfStatusChange 
----------
 1  |    1 |           Admitted |            2019-07-01 10:00 AM
----------
2  |    1   |         In Triage      |       2019-07-01 10:15 AM
----------
3  |    1       |     In Triage  |          2019-07-01 10:30 AM
----------
4   |   1   |         Surgery Scheduled  |   2019-07-01 11:00 AM
----------
5   |   1      |      In Triage     |        2019-07-01 11:30 AM
----------
6   |   1    |        Surgery Scheduled  |   2019-07-01 12:01 PM
----------
7    |  1    |        Surgery Scheduled   |  2019-07-01 12:30 PM
----------

因此,在此示例中,患者于上午10点入院。他的最新状态是“已安排手术”,而该状态的最后一次更改是“下午12:01”。因此,预期输出为:

PatientId  |    RecentStatus  |     TimeWhenStatusAppeared
----------
1    |          Surgery Scheduled  |  2019-07-01 12:01 PM 

检索最新状态非常简单,并且可以查询的查询是:

select PatientId, Status from StatusTest s1 where s1.ID = 
    ( select max(ID) from StatusTest s2 where s1.PatientId = s2.PatientId)

但是现在问题是检索这种状态的最后一次更改是一个挑战。任何能提供帮助的人,深表感谢。

谢谢。

2 个答案:

答案 0 :(得分:0)

这里不需要子查询。 ROW_NUMBER()窗口功能将一次性为您提供所需的一切。

ORDER BY子句按PatientID将结果分成组,然后TOP (1) WITH TIES子句基于ORDER BY限制返回到最新条目的行在OVER子句中。

SELECT TOP (1) WITH TIES
  PatientID,
  Status,
  TimeOfStatusChange AS TimeWhenStatusAppeared
FROM
  StatusTest
ORDER BY 
  ROW_NUMBER() OVER (PARTITION BY PatientID ORDER BY TimeOfStatusChange DESC);

答案 1 :(得分:0)

全部 以下解决方案对我有用:

/ *****

  • 选择所有列和新列以查找
  • 的先前状态
  • 通过比较当前状态来推断状态是否发生任何变化 上一个状态列
  • 介绍行号以标识每个组中的最新记录
  • 最后从给定患者的每次状态更改中获取最新信息

****** /

WITH CTE AS (
SELECT StatusDateTime, PatientId, LevelOfCare,
LAG(LevelOfCare) OVER (ORDER BY StatusDateTime) AS [PREVIOUS]
FROM StatusTest),
ALL_STATS AS (SELECT TOP 1 * FROM CTE 
UNION ALL SELECT * FROM CTE
WHERE LevelOfCare <> [PREVIOUS]
),
CTE_ROW_NUM AS (
SELECT  PatientId, StatusDateTime, LevelOfCare,
row_number() over(partition by PatientId order by PatientId,StatusDateTime desc) as RowNum
 FROM ALL_STATS 
)
select *
from CTE_ROW_NUM
where RowNum = 1;

如有任何问题,请告诉我