我正在努力想出最好的方法来增加员工的总时间。
拳击类型日期,突破,中断&一天。您可能会认为我可以选择* where date = DATE,但如果员工在晚上11:30到达并在第二天凌晨2:00离开,则无效。
我认为这样的事情可能是最好的解决方案,但我不知道它是否实用甚至可能:
从LAST RECORD中选择*,其中employee = employee STOP在第一个“clock in”实例中。
这将收集员工上次入职以来的所有打击。例如:
ID NAME TYPE TIME
约翰时间45日
46 Joe Day In TIME
47 Mary Break Out TIME
48 Joe Break Out TIME
49 Joe Break In TIME
50 John Day Out Time
51 Mary Break In TIME
52 Joe Day Out TIME
53 Mary Day Out TIME
所以在我想到的例子中,如果你正在寻找Joe的时间,它将开始从冲头ID 53向后搜索,直到它达到46号冲头。结果将是拳46,48,49和51.我然后可以计算总工作时间。再说一次,我不知道这是否可能。
我真的很感谢有关如何完成此任务的任何意见/建议,或任何其他可能更实际的方法!
答案 0 :(得分:2)
将问题分解为几个步骤,首先列出所有“IN”记录:
SELECT p_in.*
FROM punches p_in
WHERE p_in.type = 'IN'
接下来,编写子查询以查找下一个“OUT”记录(此方法假设为了简单起见,id会自动递增):
SELECT MIN(pa.id)
FROM punches pa
WHERE pa.type = 'OUT'
AND pa.name = p_in.name
AND pa.time > p_in.time
现在,将此查询包装在外观选择中,该选择看起来像打孔表:
SELECT pb.id, pb.name, pb.type, pb.time
FROM punches pb
WHERE pb.id = (
SELECT MIN(pa.id)
FROM punches pa
WHERE pa.type = 'OUT'
AND pa.name = p_in.name
AND pa.time > p_in.time
)
并在原始查询的LEFT JOIN中使用它:
SELECT
p_in.id in_id,
p_in.name in_name,
p_in.type in_type,
p_in.time in_time,
p_out.id out_id,
p_out.name out_name,
p_out.type out_type,
p_out.time out_time
FROM punches p_in
LEFT JOIN (
SELECT pb.id, pb.name, pb.type, pb.time
FROM punches pb
WHERE pb.id = (
SELECT MIN(pa.id)
FROM punches pa
WHERE pa.type = 'OUT'
AND pa.name = p_in.name
AND pa.time > p_in.time
)
) p_out
WHERE p_in.type = 'IN'
这将为您提供一个结果集,其中每个“in”记录具有下一个相应的“out”记录。如果没有相应的out记录,则out值将设置为null。
希望您可以使用这些结果来计算您的需求。
答案 1 :(得分:0)
您已经拥有了员工ID,打卡类型ID,但您错过了日期或期间ID,这将使事情变得更加轻松:
PunchId PeriodId Employee PunchTypeId PunchDateTime -------- --------- --------- ------------ -------------- ... 44 1 Mary Day In TIME 45 1 John Day In TIME 46 1 Joe Day In TIME 47 1 Mary Break Out TIME 48 1 Joe Break Out TIME 49 1 Joe Break In TIME 50 1 John Day Out TIME 51 1 Mary Break In TIME 52 1 Joe Day Out TIME 53 1 Mary Day Out TIME 54 2 John Day In TIME 55 2 Mary Day In TIME 56 2 Joe Day In TIME ...
然后你可以使用类似的东西:
select di.Employee, di.PeriodId,
timediff(do.DayOutTime, bi.BreakInTime)
+ timediff(bo.BreakOutTime, di.DayInTime) as PeriodWorkedHours
from
(
select Employee, PeriodId, PunchDateTime as DayInTime
from punches
where PunchTypeId = 'Day In'
) as di
inner join (
select Employee, PeriodId, PunchDateTime BreakOutTime
from punches
where PunchTypeId = 'Break Out'
) as bo on di.Employee = bo.Employee and di.PeriodId = bo.PeriodId
inner join (
select Employee, PeriodId, PunchDateTime as BreakInTime
from punches
where PunchTypeId = 'Break In'
) as bi on di.Employee = bi.Employee and di.PeriodId = bi.PeriodId
inner join (
select Employee, PeriodId, PunchDateTime as DayOutTime
from punches
where PunchTypeId = 'Day Out'
) as do on di.Employee = do.Employee and di.PeriodId = do.PeriodId
假设在PeriodId中,所有员工每人都有四个拳(Day In,Break Out,Break In和Day Out)。此外,PeriodId不应与处理您在问题中提到的案例的日期相关联,当时打卡时间跨越日界限。而是在插入句点的最后一拳(即Day Out punch)后为员工增加PeriodId。
答案 2 :(得分:0)
我会像下一个一样使用查询:
select workerid, sum(case
when punchtype = 'in' then -DATEDIFF(MINUTE, '20110901', punchtime)
when punchtype = 'out' then DATEDIFF(MINUTE, '20110901', punchtime)
when punchtype = 'bin' then -DATEDIFF(MINUTE, '20110901', punchtime)
when punchtype = 'bout' then DATEDIFF(MINUTE, '20110901', punchtime)
end )/60 as WorkingHours
from Punchlog
group by workerid
说明: 让我们假设我有桌子:
create table PunchLog
(workerid int not null,
punchtime datetime not null,
punchtype char(4) not null)
用几天的打孔数据。
让我们提供一些测试数据:
insert into PunchLog (workerid, punchtime, punchtype) values (1, '20110901 23:30', 'in')
insert into PunchLog (workerid, punchtime, punchtype) values (1, '20110902 03:30', 'out')
insert into PunchLog (workerid, punchtime, punchtype) values (1, '20110902 00:15', 'bin')
insert into PunchLog (workerid, punchtime, punchtype) values (1, '20110902 01:15', 'bout')
insert into PunchLog (workerid, punchtime, punchtype) values (2, '20110901 09:30', 'in')
insert into PunchLog (workerid, punchtime, punchtype) values (2, '20110901 17:00', 'out')
insert into PunchLog (workerid, punchtime, punchtype) values (2, '20110901 14:30', 'bin')
insert into PunchLog (workerid, punchtime, punchtype) values (2, '20110901 10:00', 'bout')
在工作场所度过的时间是:
T = out - in - (bin -bout) = out - in -bin + bout
其中in
,out
是日期和bin
,bout
是打卡时间。
如果我将按workerid
分组并将sum()应用于punchtime
,那么我将有工作时间,但我需要in
并且bin
时间是否定的。我也无法总结日期时间。因此,我将punchtime
更改为从过去的任何日期开始,并使用用例语句来设置符号:
sum(case
when punchtype = 'in' then -DATEDIFF(MINUTE, '20110901', punchtime)
when punchtype = 'out' then DATEDIFF(MINUTE, '20110901', punchtime)
. . .
end )/60 as WorkingHours
在我的测试中它产生结果:
workerid WorkingHours
-------- ------------
1 5
2 3