查找与日期时间相关的MIN nvarchar

时间:2014-02-12 18:17:00

标签: sql sql-server datetime min

我有一张表,其中包含患者服务列表以及他们何时到达该服务。我希望能够在紧急部门之后提供第一项服务。这是表格:

    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。我应该如何安排我的查询逻辑,以便根据最小日期时间拉出最小服务?

谢谢

2 个答案:

答案 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 APPLYROW_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