Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.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,我有一个表,其中有一个名为CHECKTIME的DATETIME列,表示员工打卡的时间。基本上,我有一个执行该功能的查询,但转换不正确。下面的例子 CHECKTIME 2014-04-28 07:58:36.000 2014-04-28 12:00:27.000 2014-04-28 13:00:02.000 2014-04-28 16:57:45.000 当实际结果为小时数=7.59时,我的查询结果为小时数=7.99 我要7.59分的结果 SELECT USERID , c

我有一个表,其中有一个名为
CHECKTIME
的DATETIME列,表示员工打卡的时间。基本上,我有一个执行该功能的查询,但转换不正确。下面的例子

CHECKTIME

2014-04-28 07:58:36.000
2014-04-28 12:00:27.000
2014-04-28 13:00:02.000
2014-04-28 16:57:45.000

当实际结果为小时数=7.59时,我的查询结果为小时数=7.99

我要7.59分的结果

SELECT  USERID
       , convert(varchar(10),CHECKTIME,101) as Date
       , SUM(CASE WHEN CHECKTYPE='I' 
                      THEN -1*(datepart(hh,[CHECKTIME])+datepart(mi,[CHECKTIME])/60.0)
                      ELSE datepart(hh,[CHECKTIME])+datepart(mi,[CHECKTIME])/60.0  END) AS Hours

FROM [CHECKINOUT]
WHERE USERID=1003
GROUP BY USERID, CONVERT(varchar(10),[CHECKTIME],101)

用以下方式表达您的查询:

with data(InTime,OutTIme) as (
    select InTime,OutTIme from (values
         (convert(datetime,'2014-04-28 07:58:36.000',120), convert(datetime,'2014-04-28 12:00:27.000',120))
        ,(convert(datetime,'2014-04-28 13:00:02.000',120), convert(datetime,'2014-04-28 16:57:45.000',120))
    )data(InTime,OutTIme)
)
select  cast(dateadd(n,sum(datediff(n,intime,outtime)),0) as time)
from data
go
结果如下:

07:59:00.0000000
在这里,我自由地手动预旋转数据,以便将注意力集中在如何构建时间转换公式上

更新:-修改为包含轴,生成相同的值:

with data(CheckTime) as (
    select CheckTime from (values
         (convert(datetime,'2014-04-28 07:58:36.000',120))
        ,(convert(datetime,'2014-04-28 12:00:27.000',120))
        ,(convert(datetime,'2014-04-28 13:00:02.000',120))
        ,(convert(datetime,'2014-04-28 16:57:45.000',120))
    )data(CheckTime)
),
pvt as (
    select
        CheckInOut
       ,[0]   as OutTime
       ,[1]   as InTime  
    from (
        select 
             CheckTime
            ,(ROW_NUMBER() over(order by CheckTime)-1) / 2 as CheckInOut
            ,(ROW_NUMBER() over(order by CheckTime)) % 2 as rn
        from data
    )t
    pivot (max(CheckTime) for rn in ([1], [0])) pvt

)
select  cast(dateadd(n,sum(datediff(n,intime,outtime)),0) as time)
from pvt
go

您提供了一个示例查询和示例数据。 但样本数据不完整。请为CHECKTYPE添加值,因为这将使我们更容易提供解决方案。 同时,它避免了彼得不得不做的任何不必要的工作/猜测。
最后,像“它不起作用”这样的回复等于没有回复,因为它不会让我们更进一步……

首先,让我们做一些测试数据:(我随意添加了一个emp id列,以便可以添加多个员工时间

DECLARE @CheckDate TABLE
(
    EmpId INT,
    CheckTime DATETIME
)

INSERT INTO @CheckDate
( EmpId, CheckTime ) 
VALUES
(1, '2014-04-28 07:58:36.000'),
(1, '2014-04-28 12:00:27.000'),
(1, '2014-04-28 13:00:02.000'),
(1, '2014-04-28 16:57:45.000'),
(2, '2014-04-27 1:00:02.000'),
(2, '2014-04-27 16:57:45.000');
现在我们做一个CTE来找到下一行,这样我们就可以得到时钟输入和时钟输出的开始和结束

;WITH CheckRows AS
(
    SELECT *,
        ROW_NUMBER() OVER (PARTITION BY EmpId ORDER BY CheckTime) RN
    FROM @CheckDate p
),
CheckBreaks AS
(
    SELECT 
        p.EmpId, 
        p.CheckTime, 
        p.RN, 
        ISNULL(n.CheckTime, 0) NextTime
    FROM CheckRows p
    INNER JOIN CheckRows n
        ON n.RN = p.RN + 1
        AND n.EmpId = p.EmpId
)
现在我们查询数据以查找基于时钟的工作分钟数(RN 1作为第一个时钟输入/时钟输出,RN 3作为第二个时钟输入/时钟输出,如果您允许更多,只需为每个组添加接下来的两个奇数)

以下是工作小时/分钟的输出:

EmpId   DiffTime    DiffHour    DiffMinute
1   479 7   59
2   957 15  57

对不起,我理解起来有点困难。你是说你的结果是以十进制小时为单位的,你想把它转换成小时和分钟吗?不,结果是以小时为单位的,但不是小数部分。99需要转换成分钟……我想是这样的……你想添加你正在处理请求的表的结构吗nd提供一个示例?问题是它们不是两个代表签入和签出的列,只有一个名为CHECKTIME…对我的原始查询有帮助吗?
EmpId   DiffTime    DiffHour    DiffMinute
1   479 7   59
2   957 15  57