我有一张表,其中包含患者服务列表以及他们何时到达该服务。我希望能够在紧急部门之后提供第一项服务。这是表格:
Service DateTimeIn
H EMERGENCY MEDICINE 2013-01-01 10:43:00.000
H MEDICINE E 2013-01-06 23:43:00.000
H MEDICINE E 2013-01-07 17:18:00.000
H MEDICINE ICU 2013-01-01 15:38:00.000
H MEDICINE ICU 2013-01-07 00:49:00.000
H MEDICINE ICU 2013-01-08 04:36:00.000
当我使用MIN(服务)服务<>' H EMERGENCY MEDICINE'它按字母顺序提取服务,这不是我需要的。我需要在紧急医疗服务后的最短时间内提供的第一项服务。在这种情况下,它将是H MEDICINE ICU。我应该如何安排我的查询逻辑,以便根据最小日期时间拉出最小服务?
谢谢
答案 0 :(得分:1)
您需要将查询过滤到仅出现在“H紧急医疗”条目之后的行,按DateTimeIn
排序,然后抓住第一个(TOP 1
)。伪代码解决方案看起来与此类似:
-- Get all Emergency visits for a given patient
WITH CTE_EmergencyVisits AS (
SELECT DateTimeIn
FROM [ServicesTable]
WHERE Services = 'H EMERGENCY MEDICINE'
AND [PatientFilter]
)
SELECT SVC.Service,
SVC.DateTimeIn
-- For each emergency visit...
FROM CTE_EmergencyVisits E
-- ... get the first service that occurred afterward
CROSS APPLY (
SELECT TOP 1
Service,
DateTimeIn
FROM [ServicesTable] S
WHERE S.[PatientIdentifier] = E.[PatientIdentifier]
AND S.DateTimeIn > E.DateTimeIn
ORDER BY
DateTimeIn ASC
) SVC
答案 1 :(得分:0)
我知道这已经过时了,但它告诉我,如果紧急记录彼此相邻,则另一个答案不会返回正确的答案。第一条记录将错误地显示第二条记录而不是零,因为在这种情况下,两个紧急情况之间不会有非紧急记录。我偶然发现了另一个查询,所以我想提供一个更新,万一其他人偶然发现了这个。
以下查询使用OUTER APPLY
代替CROSS APPLY
和ROW_NUMBER
来获得正确的下一项服务。
DECLARE @S TABLE (
[Service] NVARCHAR(40),
[DateTimeIn] DATETIME,
[PatientId] INT
)
INSERT @S
SELECT 'H EMERGENCY MEDICINE', '2013-01-01 10:43:00.000', 1
UNION ALL SELECT 'H MEDICINE E', '2013-01-06 23:43:00.000', 1
UNION ALL SELECT 'H MEDICINE E', '2013-01-07 17:18:00.000', 1
UNION ALL SELECT 'H MEDICINE ICU', '2013-01-01 15:38:00.000', 1
UNION ALL SELECT 'H EMERGENCY MEDICINE', '2013-01-07 1:41:00.000', 1
UNION ALL SELECT 'H EMERGENCY MEDICINE', '2013-01-07 1:43:00.000', 1
UNION ALL SELECT 'H MEDICINE ICU', '2013-01-07 00:49:00.000', 1
UNION ALL SELECT 'H MEDICINE ICU', '2013-01-08 04:36:00.000', 1
DECLARE @PatientId INT = 1
;WITH CTE AS (
SELECT *,
CASE WHEN S.Service = 'H EMERGENCY MEDICINE' THEN 1 ELSE 0 END AS IsEmergency,
ROW_NUMBER() OVER ( ORDER BY DateTimeIn ) AS RowNum
FROM @S S
WHERE S.PatientId = @PatientId
)
SELECT
E.Service,
E.DateTimeIn,
N.NextService,
N.NextDateTimeIn
FROM CTE E
OUTER APPLY (
SELECT TOP 1
Service AS NextService,
DateTimeIn AS NextDateTimeIn
FROM CTE
WHERE IsEmergency = 0
AND RowNum = E.RowNum + 1
) N
WHERE IsEmergency = 1
然后输出:
Service DateTimeIn NextService NextDateTimeIn
------------------------- ----------------------- ------------------------- -----------------------
H EMERGENCY MEDICINE 2013-01-01 10:43:00.000 H MEDICINE ICU 2013-01-01 15:38:00.000
H EMERGENCY MEDICINE 2013-01-07 01:41:00.000 NULL NULL
H EMERGENCY MEDICINE 2013-01-07 01:43:00.000 H MEDICINE E 2013-01-07 17:18:00.000