3

我编写了以下代码以从 SQL 中的不同行中减去(但只有那些具有相同房间和日期的行),以获得行之间的时间差异。它有效,但它错过了一些需要的场景。

我只想从彼此中减去最近的日期。下面,你会看到我的结果的开始。

     PatientName PatientName  OutTime   InTime  Room    Room    Value
     Patient A   Patient B     45:00.0  55:00.0 OR 1    OR 1    10
     Patient A   Patient C     45:00.0  55:00.0 OR 1    OR 1    130
     Patient B   Patient C     00:00.0  55:00.0 OR 1    OR 1    55

我正在尝试计算每个完成的患者和每个进来的新患者之间房间未使用的时间,但在这种情况下,我得到同一天患者之间的每个时间差(即我不希望患者 A 和患者 C 之间的区别)

我还希望能够添加案例陈述,以便如果差异大于一定数量(比如 90 分钟),则不计算在内。

请指教。

        --This code creates the table with Dummy Data

        CREATE TABLE #OperatingRoom (
        [Date] date,
        [Room] varchar(255),
    [PatientName] varchar(255),
        [InTime] time,
        [OutTime] time,
        ); 

        INSERT INTO #OperatingRoom ([Date],[Room],[PatientName],[InTime],        [OutTime])
        VALUES ('01-01-2019', 'OR 1', 'Patient A', '08:02:00','09:45:00'),
        ('01-01-2019', 'OR 1', 'Patient B', '09:55:00','11:00:00'),
        ('01-01-2019', 'OR 1', 'Patient C', '11:55:00','14:00:00'),
        ('01-02-2019', 'OR 1', 'Patient D', '08:59:00','09:14:00'),
        ('01-02-2019', 'OR 1', 'Patient E', '11:02:00','13:30:00'),
        ('01-02-2019', 'OR 2', 'Patient F', '14:02:00','16:02:00'),
        ('01-03-2019', 'OR 2', 'Patient B', '07:55:00','11:00:00'),
        ('01-03-2019', 'OR 2', 'Patient C', '11:55:00','13:00:00'),
        ('01-03-2019', 'OR 3', 'Patient D', '08:59:00','09:14:00'),
        ('01-03-2019', 'OR 2', 'Patient E', '13:02:00','13:30:00'),
        ('01-03-2019', 'OR 3', 'Patient F', '14:02:00','16:02:00')
        ;

        --This code performs the object of the query 

        SELECT 
        T1.PatientName,
        T2.PatientName,
        T1.[OutTime]
       ,T2.InTime,
        T1.Room,
        T2.Room,
        datediff(mi,T1.OutTime,T2.InTime) AS Value
        FROM #operatingroom T1
        JOIN #operatingroom T2
        ON T2.[OutTime] > T1.[InTime]
        and T1.[Date] = T2.[Date] 
        and T1.Room = T2.Room 
        and T1.PatientName <> T2.PatientName
4

2 回答 2

1

您需要对您的房间/日期进行排名,以便您可以从下一条记录中获取详细信息。像这样的东西:

 WITH Myrooms as (
      Select  Date, 
              Room, 
              PatientName, 
              InTime,
              OutTime, 
              DENSE_RANK() OVER (PARTITION BY Room, Date ORDER BY InTime) as PatientRank 
      From #OperatingRoom )

  Select Date, 
         Room, 
         PatientName, 
         M.InTime, 
         OutTime,
         CASE WHEN DateDiff(mi,M.OutTime, aa.InTime) >90 then NULL 
         else DateDiff(mi,M.OutTime, aa.InTime) END as Value 
  from Myrooms M
  OUTER APPLY
  (Select InTime from MyRooms MM 
   WHERE MM.Room=M.Room and MM.Date=M.Date and MM.PatientRank=M.PatientRank+1) aa
于 2019-03-27T18:25:02.967 回答
0

编辑

我更进一步,为您提供了一种方法来查找房间使用之间的平均时间,并能够设置忽略的间隔。

SQL小提琴

查询

DECLARE @OnlyCountMinutes int 
SET @OnlyCountMinutes = 90  
DECLARE @OnlyCountSeconds int  
SET @OnlyCountSeconds = @OnlyCountMinutes*60 


SELECT s1.Room
    , AVG(secSinceLast) / 60.0 AS minutesSinceLast
FROM
(
  SELECT
       Room
     , InTime
     , OutTime
     , LEAD(InTime) OVER (PARTITION BY Room ORDER BY InTime) AS nextIn
     , LAG(OutTime) OVER (PARTITION BY Room ORDER BY OutTime) AS prevOut
     , DATEDIFF(second, LAG(OutTime) OVER (PARTITION BY Room ORDER BY OutTime), InTime) AS secSinceLast
     -- , DATEDIFF(second, outTime, LEAD(InTime) OVER (PARTITION BY Room ORDER BY InTime)) AS secUntilNext
  FROM OperatingRoom
) s1
WHERE ISNULL(s1.secSinceLast,@OnlyCountSeconds+1) < @OnlyCountSeconds
    -- AND ISNULL(s1.secUntilNext,@OnlyCountSeconds+1) < @OnlyCountSeconds
GROUP BY s1.Room
ORDER BY s1.Room

结果

| Room | minutesSinceLast |
|------|------------------|
| OR 1 |             32.5 |
| OR 2 |             28.5 |

就像我上面的建议一样,我将日期和时间合并到一个字段中。这将使我们能够跨越几天。然后,我为您声明一个变量,以将您想要设置的分钟数设置为要忽略的最小空闲时间。我将其转换为秒。这并不是真正需要的,特别是如果您不跟踪秒数或不在乎间隔之间的秒数。我切换到使用LAG()窗口功能(SQL2012 中也添加了该功能),因为您真的更关心条目之前发生的事情而不是之后发生的事情。然后我只使用标准聚合来计算每个房间的平均间隔,不包括你之前设定的限制。

- - - - - - - - - - 原来的 - - - - - - - - - -

好消息是,在 SQL 2012 中,您可以使用LEAD()窗口函数。

SQL小提琴

使用上面的设置信息查询

SELECT Room
    , PatientName
    , Date
    , InTime
    , OutTime
    , nextIn
    , gapDiffInSeconds = DATEDIFF(second,OutTime,nextIn)
FROM
(
  SELECT
       PatientName
     , Room
     , [Date]
     , InTime
     , OutTime
     , nextIn     = LEAD(InTime) OVER (PARTITION BY [Room],[Date] ORDER BY [Date],[OutTime])
  FROM OperatingRoom
) s1
WHERE DATEDIFF(second,OutTime,nextIn) > 1
    -- AND DATEDIFF(second,OutTime,nextIn) < 5400 /* 60 seconds * 90 minutes = 5400 seconds */
ORDER BY Room, Date, InTime, OutTime

结果

| Room | PatientName |       Date |           InTime |          OutTime |           nextIn | gapDiffInSeconds |
|------|-------------|------------|------------------|------------------|------------------|------------------|
| OR 1 |   Patient A | 2019-01-01 | 08:02:00.0000000 | 09:45:00.0000000 | 09:55:00.0000000 |              600 |
| OR 1 |   Patient B | 2019-01-01 | 09:55:00.0000000 | 11:00:00.0000000 | 11:55:00.0000000 |             3300 |
| OR 1 |   Patient D | 2019-01-02 | 08:59:00.0000000 | 09:14:00.0000000 | 11:02:00.0000000 |             6480 |
| OR 2 |   Patient B | 2019-01-03 | 07:55:00.0000000 | 11:00:00.0000000 | 11:55:00.0000000 |             3300 |
| OR 2 |   Patient C | 2019-01-03 | 11:55:00.0000000 | 13:00:00.0000000 | 13:02:00.0000000 |              120 |
| OR 3 |   Patient D | 2019-01-03 | 08:59:00.0000000 | 09:14:00.0000000 | 14:02:00.0000000 |            17280 |

如果您想过滤掉超过特定时间的 OR 访问,请取消注释AND DATEDIFF(...)...上述查询并使用SECONDS您希望差异的适当数量。

于 2019-03-27T19:31:54.323 回答