Рассчитать данные о расписании сотрудников - PullRequest
0 голосов
/ 21 мая 2018

Предположим, у вас есть таблица временных часов с только записью временной метки для каждого события временного синхронизации:

Userid  CheckTime
312     2018-05-08 05:52:00
312     2018-05-08 18:06:00
312     2018-05-10 05:55:00
312     2018-05-10 18:00:00
312     2018-05-11 05:58:00
312     2018-05-11 18:00:00
312     2018-05-12 05:35:00
312     2018-05-12 18:00:00

Как я могу подсчитать события в SQL Server, чтобы они отображались следующим образом?

Day       Date       In      Out        Reg      OT
Tuesday   5/8/2018   5:52AM  6:06PM     12.00    0.00
Thursday  5/10/2018  5:55AM  6:00PM     12.00    0.00
Friday    5/11/2018  5:58AM  6:00PM     12.00    0.00
Saturday  5/12/2018  5:35AM  6:00PM     12.00    0.42

Кроме того, у нас есть люди, которые в одночасье начинают свою смену и переносят ее в другой день.

Я не уверен, как рассчитать это, поскольку он основан на строках и столбцах.

Я пробовал это ... но это не работает правильно ...

         ;WITH emp
                 AS (SELECT [UserID],
                            [CheckTime],
                    CAST([CheckTime] AS DATE) AS [Day],
                    Row_Number()
                    OVER( PARTITION BY [UserID], CAST([CheckTime] AS DATE)
                     ORDER BY [UserID], [CheckTime]) AS [RowNumber]
                     FROM   [dbo].[Clock_Data] WHERE CHECKTIME 
                     BETWEEN '2018-05-06' AND '2018-05-13')
            SELECT 
             t1.[UserID], 
             E.[Last Name]AS [EMPID],
                   MIN(t1.[CheckTime]) AS [time_in],
                   MAX(t2.[CheckTime]) AS [time_out],
                   CAST((SUM(ISNULL(DATEDIFF(ss,  t1.[CheckTime], 
            t2.[CheckTime]) , 0)) / 3600)-1 AS VARCHAR(10)) + '.' +
            FROM   emp AS t1
                   LEFT JOIN emp AS t2
                          ON ( t1.[UserID] = t2.[UserID]
                               AND t1.[Day] = t2.[Day]
                               AND t1.[RowNumber] = ( t2.[RowNumber] - 1 )
                               AND t2.[RowNumber] % 2 = 0 
                               )
                    INNER JOIN Employees as E on t1.Userid = E.[ID Number]
            GROUP  BY t1.[UserID], E.[Last Name]
            ORDER  BY t1.[UserID]

1 Ответ

0 голосов
/ 21 мая 2018

Как упомянуто в комментариях выше, в этом типе запроса МНОГО сложностей.Пропущенные / дублирующие удары.Летнее время.Праздники, выходные.Типы вещей, которые могут считаться O / T для любых правил, которые вам нужны.Но для хорошего чистого набора данных, как у вас, вы можете сделать это довольно легко.Это ни в коем случае не является полным решением, потому что у вас есть много вещей, чтобы сгладить детали.Но это должно послужить достойной отправной точкой.

declare @Something table
(
    Userid int
    , CheckTime datetime
)

insert @Something values
    (312, '2018-05-08 05:52:00')
    , (312, '2018-05-08 18:06:00')
    , (312, '2018-05-10 05:55:00')
    , (312, '2018-05-10 18:00:00')
    , (312, '2018-05-11 05:58:00')
    , (312, '2018-05-11 18:00:00')
    , (312, '2018-05-12 05:35:00')
    , (312, '2018-05-12 18:00:00');

with OrderedResults as
(
    select *
        , RowNum = ROW_NUMBER() over(partition by Userid order by CheckTime)
    from @Something
)
, InPunch as
(
    select *
        , GroupNum = Row_Number () over(partition by Userid order by RowNum)
    from OrderedResults
    where RowNum % 2 = 1
)
, OutPunch as 
(
    select *
        , GroupNum = Row_Number () over(partition by Userid order by RowNum)
    from OrderedResults
    where RowNum % 2 = 0
)

select ip.Userid
    , PunchDate = convert(date, ip.CheckTime)
    , CheckIn = ip.CheckTime
    , CheckOut = op.CheckTime
from InPunch ip
join OutPunch op on op.GroupNum = ip.GroupNum
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...