SQL Server рассчитывает рабочее время с несколькими IN OUT - PullRequest
0 голосов
/ 13 июня 2018

У меня есть таблица с журналами посещаемости сотрудников с сенсорных машин, сотрудники могут иметь несколько записей IN & OUT за один день, я хочу рассчитать количество часов, в течение которых занятость оставалась IN (общее количество рабочих часов), игнорируя Time OUTЯ искал это решение в течение двух дней, но не смог получить требуемый результат.

Таблица журналов такая же, как и в (checkin_out_log)

╔════════╦═══════╦═════════════════════════╦════════════╗
║ emp_id ║ shift ║       check_time        ║ check_type ║
╠════════╬═══════╬═════════════════════════╬════════════╣
║      2 ║     1 ║ 2018-02-22 07:00:44.000 ║ C-IN       ║
║      2 ║     1 ║ 2018-02-22 13:00:35.000 ║ B-OUT      ║
║      2 ║     1 ║ 2018-02-22 13:30:46.000 ║ B-IN       ║
║      2 ║     5 ║ 2018-02-22 16:00:55.000 ║ C-OUT      ║
╚════════╩═══════╩═════════════════════════╩════════════╝

Желаемый результат:

╔════════╦══════════╦═════════════════════════╦════════════╗
║ emp_id ║  IN Hrs  ║       Date              ║ OUT HRS    ║
╠════════╬══════════╬═════════════════════════╬════════════╣
║      2 ║ 08:30    ║ 2018-01-22              ║ 00:30      ║
╚════════╩══════════╩═════════════════════════╩════════════╝

Вот данные в запросе

Вот что я получаю в результатах с данными, показанными на скриншоте вместе с вашим запросом, пожалуйста, укажите, что не так

1 Ответ

0 голосов
/ 13 июня 2018

Предполагая, что IN и OUT всегда в паре.

Вы можете использовать оконную функцию LEAD (), чтобы получить следующий check_time.И используйте условие CASE WHEN для определения времени IN или OUT

select  emp_id, 
        in_hrs = sum(in_mins) / 60.0, 
        check_date = convert(date, check_time), 
        out_hrs = sum(out_mins) / 60.0
from
(
    select  *, 
            in_mins = CASE  WHEN    check_type in ('C-IN', 'B-IN')
                            AND     LEAD(check_type) OVER (PARTITION BY emp_id ORDER BY check_time) in ('C-OUT', 'B-OUT')
                            THEN    DATEDIFF(MINUTE, 
                                             check_time, 
                                             LEAD(check_time) OVER (PARTITION BY emp_id ORDER BY check_time))
                            ELSE    0
                            END,
            out_mins= CASE  WHEN    check_type in ('C-OUT', 'B-OUT')
                            AND     LEAD(check_type) OVER (PARTITION BY emp_id ORDER BY check_time) in ('B-IN')
                            THEN    DATEDIFF(MINUTE, 
                                             check_time, 
                                             LEAD(check_time) OVER (PARTITION BY emp_id ORDER BY check_time))
                            ELSE    0
                            END
    from    checkin_out_log
) d
group by emp_id, convert(date, check_time)

Edit: добавлено условие для проверки случаев, когда IN без OUT или наоборот.Вход / выход будет игнорироваться, и вычисления не будут выполняться.

Добавлены следующие условия:

LEAD(check_type) OVER (PARTITION BY emp_id ORDER BY check_time) in ('C-OUT', 'B-OUT')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...