首页 > 解决方案 > 两次之间的班次次数

问题描述

你能帮我解决以下问题吗?

我正在尝试计算患者在医院的轮班情况。班次时间从7:00 AMto6:59 PM7:00 PMto开始6.59 AM

如果患者在轮班开始后被收治到某个地点,我们将在总计算中忽略该轮班。

这是示例数据以及最终结果的外观:

DECLARE @T AS TABLE
(
    ID          INT,
    LOCATION VARCHAR(10),
    Date_entered DATETIME,
    date_left datetime
);

DECLARE @endresult AS TABLE
(
    ID          INT,
    LOCATION VARCHAR(10),
    Date_entered DATETIME,
    date_left datetime,
    Total_shifts int
)


insert into @T VALUES
(1,'AB','01/01/2019 07:10','01/01/2019 20:30'), 
(2,'CD','01/01/2019 20:30','01/04/2019 02:30'), 
(3,'EF','01/04/2019 02:30','01/07/2019 19:30'), 
(4,'GH','01/07/2019 19:30','01/08/2019 13:30')


insert into @endresult VALUES
(1,'AB','01/01/2019 07:10','01/01/2019 20:30',1), 
(2,'CD','01/01/2019 20:30','01/04/2019 02:30',4), 
(3,'EF','01/04/2019 02:30','01/07/2019 19:30',8), 
(4,'GH','01/07/2019 19:30','01/08/2019 13:30',1) 

SELECT * FROM @t

select * from @endresult

我尝试使用递归 CTE,但查询需要太多时间才能完成。有什么简单的计算时间的方法吗?

标签: sqltsqlsql-server-2012

解决方案


这是一个为您的示例数据返回正确结果的查询:

select 
    t.*, 
    DATEDIFF(DAY, date_entered, date_left) * 2
        - CASE WHEN DATEPART(HOUR, date_entered) < 7 THEN 0 WHEN DATEPART(HOUR, date_entered) < 19 THEN 1 ELSE 2 END
        + CASE WHEN DATEPART(HOUR, date_left)    < 7 THEN 0 WHEN DATEPART(HOUR, date_left)    < 19 THEN 1 ELSE 2 END
    AS Total_shifts
from @t t;

逻辑是先计算进出之间发生了多少天,然后将其乘以 2 得到原始的班次数;然后通过检查患者进入和退出的时间来调整原始计数。

DB Fiddle上的这个演示与您的示例数据返回:

身份证 | 位置 | 输入日期 | 日期左 | 总班次
-: | :------- | :----------------- | :----------------- | ------------:
 1 | AB | 01/01/2019 07:10:00 | 2019 年 1 月 1 日 20:30:00 | 1
 2 | 光盘 | 2019 年 1 月 1 日 20:30:00 | 04/01/2019 02:30:00 | 4
 3 | 英孚 | 04/01/2019 02:30:00 | 2019 年 7 月 1 日 19:30:00 | 8
 4 | 生长激素 | 2019 年 7 月 1 日 19:30:00 | 2019 年 8 月 1 日 13:30:00 | 1

推荐阅读