Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 计算员工时间表数据_Sql_Sql Server_Sql Server 2008 - Fatal编程技术网

Sql 计算员工时间表数据

Sql 计算员工时间表数据,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,假设您有一个时钟表,每个时钟事件只有一个时间戳条目: 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 2

假设您有一个时钟表,每个时钟事件只有一个时间戳条目:

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]

如上所述,这种类型的查询有很多复杂性。漏打/重复打孔。夏时制。假日,周末。对于您需要的任何规则,可以算作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

如上所述,这种类型的查询有很多复杂性。漏打/重复打孔。夏时制。假日,周末。对于您需要的任何规则,可以算作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

这类查询比表面上看起来要复杂得多,我们提供给您的任何查询都需要对它有相同的理解才能维护它。需要考虑的事项:遗漏的打孔、意外的双打孔和为避免打孔而进行的节流、跨越日边界的打孔以及夏时制转换期间时钟位置的持续时间计算,根据时钟位置是否与服务器同步时间,用于加班和正常工作时间计算的特定于域的业务逻辑,等等。我建议将其分成几个较小的部分,并使用利用这些功能的函数和视图,然后在此基础上构建一个更易于管理的查询或过程。有一些东西可以限制不同的打孔,有一些东西可以在打孔之后填充缺少的打孔,有一些东西可以将打孔分类为输入或输出,有一些东西可以在打孔之后考虑夏令时,有一些东西可以包括你的业务逻辑来计算之后的费率,等等,然后有一个视图或过程来使用所有这些。请记住,如果对数据进行了追溯性修改,则可能需要重新运行。这实际上是由一个时钟系统来维持的。时钟数据被拉出,这将确保时钟进入/时钟退出状态。这种查询比表面上看起来要复杂得多,我们给你的任何查询都需要对它有相同的理解才能维护它。需要考虑的事项:遗漏的打孔、意外的双打孔和为避免打孔而进行的节流、跨越日边界的打孔以及夏时制转换期间时钟位置的持续时间计算,根据时钟位置是否与服务器同步时间,用于加班和正常工作时间计算的特定于域的业务逻辑,等等。我建议将其分成几个较小的部分,并使用利用这些功能的函数和视图,然后在此基础上构建一个更易于管理的查询或过程。有一些东西可以限制不同的打孔,有一些东西可以在打孔之后填充缺少的打孔,有一些东西可以将打孔分类为输入或输出,有一些东西可以在打孔之后考虑夏令时,有一些东西可以包括你的业务逻辑来计算之后的费率,等等,然后有一个视图或过程来使用所有这些。请记住,如果对数据进行了追溯性修改,则可能需要重新运行。这实际上是由一个时钟系统来维持的。时钟数据被拉出,这将确保时钟进入/时钟退出状态。没有重拳,是的,我不确定这是否是一个好的起点……Userid PunchDate
code ID PunchDate签入签出2012-04-25 2012-04-25 12:05:00 2012-04-25 13:02:00 2012-04-25 2012-04-25 12:05:00 2012-04-26 12:03:00 2012-04-25 2012-04-04-25 12:05:00 2012-04-25 14:22:00 2012-04-25 2012-04-04-04-25 12:05:00 2012-04-2617:09:00
@edwardhoades-注释不适合格式化,也不确定数据试图显示什么。我很好奇为什么你认为这不是一个好的起点。它返回的数据行与OP请求的数据行相同。我只是没有包括DATEDIFF部分是的,我不确定这是否是一个好的起点……Userid PunchDate
code ID PunchDate签入签出2012-04-25 2012-04-25 12:05:00 2012-04-25 13:02:00 2012-04-25 2012-04-25 12:05:00 2012-04-26 12:03:00 2012-04-25 2012-04-04-25 12:05:00 2012-04-25 14:22:00 2012-04-25 2012-04-04-04-25 12:05:00 2012-04-2617:09:00
@edwardhoades-注释不适合格式化,也不确定数据试图显示什么。我很好奇为什么你认为这不是一个好的起点。它返回的数据行与OP请求的数据行相同。我只是没有包括DATEDIFF部分。