SQL 根据连续任务获取班次开始和班次结束

SQL get start of shift and end of shift based off consecutive tasks

我需要根据班次中的任务获得班次的真实长度。没有班次开始和结束时间的记录,只有每个任务的开始和结束。我一直在尝试获取轮班开始的时间和轮班结束的时间。或者以分钟为单位的班次长度。

|----|-------------|-----------|-------------------|-------------------|-----------|--------|  
| ID | EMPLOYEE_ID | TASK_TYPE |        START_TIME |          END_TIME | START_DAY | LENGTH |
|----|-------------|-----------|-------------------|-------------------|-----------|--------|
|  1 |       12344 |    TASK A | 28-Sep-2018 11:00 | 28-Sep-2018 12:00 |     43371 |     60 |
|  2 |       12344 |    TASK C | 28-Sep-2018 12:00 | 28-Sep-2018 19:00 |     43371 |    420 |
|  3 |      457547 |    TASK C | 28-Sep-2018 19:00 | 28-Sep-2018 21:00 |     43371 |    120 |
|  4 |      457547 |    TASK F | 28-Sep-2018 21:00 | 28-Sep-2018 23:00 |     43371 |    120 |
|  5 |      457547 |    TASK C | 28-Sep-2018 23:00 | 29-Sep-2018 02:00 |     43371 |    180 |
|  6 |       12344 |    TASK A | 30-Sep-2018 08:00 | 30-Sep-2018 14:00 |     43373 |    360 |
|----|-------------|-----------|-------------------|-------------------|-----------|--------|

以下 SQL 的字符串创建上面的 table。

SELECT quintiq_id, 
   employee_id, 
   task_type, 
   Cast(start_time AS DATETIME)               AS START_TIME, 
   Cast(end_time AS DATETIME)                 AS END_TIME, 
   Cast(Cast(start_time AS DATE) AS DATETIME) AS START_DAY, 
   Datediff(minute, start_time, end_time)     AS LENGTH 
FROM   daysheet_active_shift 
WHERE  ( NOT task_type = 'OFF' ) 
   AND ( NOT task_type = 'OFF*' ) 
   AND employee_id <> 0; 

task_type OFFOFF* 的过滤很重要,因为它们 link 所有任务在一起所以有一个关闭的开始和结束时间之间每个班次。

我只有对数据库后端的读取权限,并且只有 Access 2013 运行 查询作为传递查询。我试图将上面的查询转换为递归查询以获得轮班的总长度。但是我根本无法达到 运行。是的,累积查询确实在服务器上工作。有什么想法吗??

WITH L AS (
       SELECT QUINTIQ_ID,
                    EMPLOYEE_ID, 
                    TASK_TYPE, 
                    START_TIME, 
                    END_TIME, 
                    datediff(minute, START_TIME, END_TIME) as LENGTH, 
                    0 as TOT 
       FROM DAYSHEET_ACTIVE_SHIFT 
       WHERE QUNITIQ_ID IN (
              SELECT A.QUINTIQ_ID
              FROM DAYSHEET_ACTIVE_SHIFT AS A LEFT JOIN DAYSHEET_ACTIVE_SHIFT AS B ON
                     (A.EMPLOYEE_ID = B.EMPLOYEE_ID) And (A.START_TIME = B.END_TIME)
              WHERE B.QUINTIQ_ID IS NOT NULL 
                            AND (NOT A.TASK_TYPE = 'OFF') 
                            AND (NOT A.TASK_TYPE = 'OFF*') 
                            AND A.EMPLOYEE_ID <> 0
              )
      UNION ALL

      SELECT C.QUINTIQ_ID,
                    C.EMPLOYEE_ID, 
                    C.TASK_TYPE, 
                    C.START_TIME, 
                    C.END_TIME, 
                    datediff(minute, C.START_TIME, C.END_TIME) as LENGTH, 
                    C.TOT + D.TOT as TOT 
      FROM  DAYSHEET_ACTIVE_SHIFT AS C JOIN L AS D ON 
                    (C.EMPLOYEE_ID = D.EMPLOYEE_ID) And (D.START_TIME = 
C.END_TIME)
       )

SELECT * FROM L

我希望查询产生什么:

|----|-------------|-----------|-------------------|-------------------|-----------|--------|-----|  
| ID | EMPLOYEE_ID | TASK_TYPE |        START_TIME |          END_TIME | START_DAY | LENGTH | TOT |
|----|-------------|-----------|-------------------|-------------------|-----------|--------|-----|
|  1 |       12344 |    TASK A | 28-Sep-2018 11:00 | 28-Sep-2018 12:00 |     43371 |     60 | 480 |
|  2 |       12344 |    TASK C | 28-Sep-2018 12:00 | 28-Sep-2018 19:00 |     43371 |    420 | 480 |
|  3 |      457547 |    TASK C | 28-Sep-2018 19:00 | 28-Sep-2018 21:00 |     43371 |    120 | 420 |
|  4 |      457547 |    TASK F | 28-Sep-2018 21:00 | 28-Sep-2018 23:00 |     43371 |    120 | 420 |
|  5 |      457547 |    TASK C | 28-Sep-2018 23:00 | 29-Sep-2018 02:00 |     43371 |    180 | 420 |
|  6 |       12344 |    TASK A | 30-Sep-2018 08:00 | 30-Sep-2018 14:00 |     43373 |    360 | 360 |

|  7 |       12344 |    TASK A | 02-Oct-2018 06:00 | 02-Sep-2018 14:00 |     43375 |    480 | 480 |

|  8 |       12344 |    TASK A | 02-Oct-2018 23:00 | 03-Oct-2018 06:00 |     43375 |    420 | 420 |

|  9 |       12344 |    TASK A | 06-Oct-2018 08:00 | 06-Oct-2018 09:00 |     43379 |     60 | 420 |
| 10 |       12344 |    TASK B | 06-Oct-2018 09:00 | 06-Oct-2018 15:00 |     43379 |    360 | 420 |

| 11 |       12344 |    TASK A | 06-Oct-2018 22:00 | 07-Oct-2018 04:00 |     43379 |    360 | 480 |
| 12 |       12344 |    TASK A | 07-Oct-2018 04:00 | 06-Oct-2018 06:00 |     43380 |    120 | 480 |
|----|-------------|-----------|-------------------|-------------------|-----------|--------|-----|

这是您要找的吗?

SELECT 
    quintiq_id               
,   employee_id     
,   task_type       
,   start_time      
,   end_time
,   DATEDIFF(DAY, '1899-12-30T00:00:00', start_time)  START_DAY
,   CASE WHEN DATEDIFF(MINUTE, start_time, end_time) < 1 THEN DATEDIFF(MINUTE, end_time, start_time) ELSE DATEDIFF(MINUTE, start_time, end_time) END  [LENGTH]
,   SUM(CASE WHEN DATEDIFF(MINUTE, start_time, end_time) < 1 THEN DATEDIFF(MINUTE, end_time, start_time) ELSE DATEDIFF(MINUTE, start_time, end_time) END) OVER(PARTITION BY EMPLOYEE_ID,  CAST(end_time AS DATE)) TOT
FROM 
    daysheet_active_shift
WHERE  
    ( NOT task_type = 'OFF' ) 
AND ( NOT task_type = 'OFF*' ) 
AND employee_id <> 0