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 OFF
和 OFF*
的过滤很重要,因为它们 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
我需要根据班次中的任务获得班次的真实长度。没有班次开始和结束时间的记录,只有每个任务的开始和结束。我一直在尝试获取轮班开始的时间和轮班结束的时间。或者以分钟为单位的班次长度。
|----|-------------|-----------|-------------------|-------------------|-----------|--------|
| 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 OFF
和 OFF*
的过滤很重要,因为它们 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