我编写了以下代码,以从SQL的不同行中减去(但仅从具有相同Room和Date的行中减去),以获得行之间的时间差。它可以工作,但是错过了一些所需的方案。
我只想彼此减去最近的日期。在下面,您会看到我的结果的开始。
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
答案 0 :(得分: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
答案 1 :(得分:0)
编辑
我又走了一步,为您提供了一种方法来查找两次房间使用之间的平均时间,并可以设置忽略间隔。
查询:
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
Results :
| Room | minutesSinceLast |
|------|------------------|
| OR 1 | 32.5 |
| OR 2 | 28.5 |
就像我上面的建议一样,我将日期和时间合并到一个字段中。这将使我们能够跨越几天。然后,我为您声明一个变量,以将要设置的分钟数设置为可忽略的最小空闲时间。我将其转换为秒。这并不是真正需要的,尤其是如果您不跟踪秒数或不关心间隔之间有多少秒。我转而使用LAG()
窗口函数(在SQL2012中也添加了),因为您实际上更关心条目之前发生的事情和条目之后发生的事情。然后,我仅使用标准聚合来计算每个房间的平均间隔(不包括您之前设置的限制)。
--------------------原始--------------------
好消息是,在SQL 2012中,您可以使用LEAD()
窗口函数。
使用上面的设置信息查询:
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
Results :
| 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
。