基于多行的时间计算

时间:2017-01-25 19:23:13

标签: sql sql-server sql-server-2008

我试图找出打卡/打卡时间是否与2016年为每位员工工作的总次数相符。

SELECT CONVERT(varchar, PUNCH, 103), JOBDATE, EMPLOYEE, JOB, HOURS
FROM JOBTABLE
WHERE JOBDATE = convert(int, convert(varchar(10), getdate(), 112))
AND EMPLOYEE = 105

表:

PUNCH   JOBDATE EMPLOYEE    JOB     HOURS
0600    20170123    105     AA785   7
1024    20170123    105     AA258   0.5
0600    20170123    105    LOGIN    0
1558    20170123    105    LOGIN    0

在这一天的例子中,员工105打了600,并在1558(下午3:58)打了一拳。该字段是一个字符。除了一个关键领域之外,没有办法真正说出打入和打出之间的区别。打卡输入的数量低于打卡数量,没有其他押韵或理由。

所以这个人工作了大约10个小时。但是,如果你加上他的工作时间,它就会增加到7.5。我需要知道这种差异。如果他的总工作时间少于他的拳头,那那就是一个大问题。我需要知道一年的总和。所以对于105,他的时间是2.5小时。

我不知道如何计算工作时间,因为它们是两个独立的行。然后每天为每位员工查看每一行。有人可以帮忙吗?非常感谢!!

employee    jobdate    sumHours DiffHours   ScheduledHours
105         20170123    7.5    -2.466666    10
105         20170124    1.5    -6.5         8

----------------------------------------------- ---------------------------------

更多测试数据

Job         Hours   Punch   
123456X     0.98    0301    20160412
123451      1.75    0000    20160412
123452      1.27    0145    20160412
LOGIN       0       2345    20160412
LOGIN       0       0346    20160412
123453      0.25    2345    20160412

所以这看起来他是第三班,但他先工作。我认为必须加入。有一个班次专栏,谢天谢地。无论如何,他工作4.25小时这是正确的,但它说他被安排在20分钟.minPunch和maxPunch是226和1425,他们应该是346和2345.

2 个答案:

答案 0 :(得分:0)

您需要加入两行与日期和员工匹配的数据,但不能加入;所以你加入桌子对抗自己:

SELECT CONVERT(varchar, A.PUNCH, 103) AS PUNCH_A, CONVERT(varchar, B.PUNCH, 103) AS PUNCH_B, A.JOBDATE, A.EMPLOYEE, A.JOB, A.HOURS + B.HOURS as TOTALHOURS
    FROM JOBTABLE A
    INNER JOIN JOBTABLE B
        ON A.JOBDATE = B.JOBDATE AND A.EMPLOYEE=B.EMPLOYEE AND A.JOB=B.JOB
           AND A.JOB <> 'LOGIN'
           AND A.PUNCH<B.PUNCH -- this is what makes sure A is the punch in and B punch out
    WHERE A.JOBDATE = convert(int, convert(varchar(10), getdate(), 112))
      AND A.EMPLOYEE = 105

答案 1 :(得分:0)

您可以将打孔转换为分钟,将小时转换为分钟。从那里你可以检查是否小时&lt; (maxpunch - minpunch)

这可能会让你朝着正确的方向前进:

rextester:http://rextester.com/ZRXH77147

create table t (
    punch char(4)
  , jobdate char(8)
  , employee int 
  , job char(5)
  , hours decimal(5,2)
);

insert into t values
 ('0600','20170123',105,'AA785',7)
,('1024','20170123',105,'AA258',0.5)
,('0600','20170123',105,'LOGIN',0)
,('1558','20170123',105,'LOGIN',0);

查询:

with cte as (
  select 

        employee
      , jobdate
      , minPunch = min(case 
                       when job = 'login' 
                         then (convert(int,left(Punch,2))*60.0)
                               +convert(int,right(Punch,2))
                       else null 
                       end
                    )
      , maxPunch = max(case 
                       when job = 'login' 
                         then (convert(int,left(Punch,2))*60.0)
                               +convert(int,right(Punch,2))
                       else null 
                       end
                    )
      , sumHours = sum(hours)
    from t
    group by 
        employee
      , jobdate
)
select 
      Employee
    , jobdate
    , SumHours
    , diffHours = convert(decimal(9,2)
                 ,round(((maxPunch-minPunch)-(sumHours*60.0))/60.0,1)
                 )
    , ScheduledHours = convert(decimal(9,2),round((maxPunch-minPunch)/60.0,1))
  from cte 

返回:

+----------+----------+----------+-----------+----------------+
| Employee | jobdate  | SumHours | diffHours | ScheduledHours |
+----------+----------+----------+-----------+----------------+
|      105 | 20170123 | 7,50     | -2,50     | 10,00          |
+----------+----------+----------+-----------+----------------+