2017-12-01 7 views
1

우리가 일하는 도시 중 하나에서 시행되는 새로운 법률이 있습니다. 누군가가 클럭 아웃 할 때까지 최소 11 시간이 있어야합니다. 시간이 11 시간 미만이면 각 사건에 대해 일정 금액을 지불해야합니다. 나는 SQL 서버를 사용하고교대 근무 시간 계산

2012

나는 각 사람이 교대 사이에 얼마나 많은 시간을 결정할에 도움이 필요합니다. 아래 기록을 토대로 11/14 11:28 pm -> 11/15 8:56 am (9.28 시간) 및 11/29 2:32 am -> 11/29 10:11 am (7.39 시간)

CREATE TABLE #Shift(
    FKEmployeeNumber int, 
    DateOfBusiness datetime, 
    FKStoreId int, 
    EmployeeShiftNumber int, 
    FKJobCodeId int, 
    InHour int, 
    InMinute int, 
    OutHour int, 
    OutMinute int) 

insert into #Shift (FKEmployeeNumber, DateOfBusiness, FKStoreId, EmployeeShiftNumber, FKJobCodeId, InHour, InMinute,OutHour,OutMinute) 
values 
(529251, '11/13/2017', 3013, 0, 1, 8, 1, 16, 24), 
(529251, '11/14/2017', 3013, 0, 1, 15, 21, 23, 28), 
(529251, '11/15/2017', 3013, 0, 1, 8, 56, 15, 58), 
(529251, '11/16/2017', 3013, 0, 1, 14, 59, 20, 54), 
(529251, '11/19/2017', 3013, 0, 1, 12, 40, 19, 42), 
(529251, '11/20/2017', 3013, 1, 1, 8, 28, 23, 47), 
(529251, '11/21/2017', 3013, 0, 1, 15, 31, 23, 30), 
(529251, '11/25/2017', 3013, 0, 1, 10, 26, 18, 13), 
(529251, '11/27/2017', 3013, 0, 1, 9, 58, 18, 27), 
(529251, '11/28/2017', 3013, 0, 1, 14, 59, 2, 32), 
(529251, '11/29/2017', 3013, 0, 1, 10, 11, 17, 13), 
(529251, '11/29/2017', 3013, 1, 1, 17, 16, 17, 25), 
(529251, '11/30/2017', 3013, 0, 1, 15,4, 20, 0), 
(529251, '11/30/2017', 3013, 1, 1, 20, 0, 23, 18), 
(529251, '11/30/2017', 3013, 2, 1, 23, 18, 23, 22), 
(529251, '12/01/2017', 3013, 0, 1, 12, 12, 16, 0) 


Select 
sh.dateofbusiness,sh.fkstoreid,sh.employeeshiftnumber,sh.fkemployeenumber, sh.fkjobcodeid,sh.inHour,sh.InMinute,sh.OutHour,sh.OutMinute 
from #shift sh where sh.dateofbusiness > '11/12/2017' and sh.fkemployeenumber = 529251 
order by sh.FKEmployeeNumber, sh.DateOfBusiness 
+0

당신은 실수로 각 timepart에 대해 별도의 정수 필드와 시간을 저장했다. 결과적으로 이것은 재미 있지 않을 것입니다. 필자는 이러한 것들을 적당한 타임 스탬프 데이터 타입으로 변환하고, 이전의 것을 얻기 위해'LAG (yourtimestamp) OVER (PARTITION BY FKEmployeeNumber ORDER BY DateOfBusiness DESC) '를 사용하여 다음 레코드로부터 하나의 레코드를 뺄 수 있도록 제안 할 것입니다. 현재 기록에 대한 시간 기록 세부 사항. 그렇지 않으면 상처를 입을 수 있습니다. – JNevill

+0

우리는 POS 공급자로부터 우리에게 복제 된 데이터를받습니다. 시간과 분은 별도의 열에 있으므로이 문제를 제어 할 수 없습니다. – user3446684

+0

POS의 단편은 Sh **의 단편입니까? ;) 나는 실제 시간과 아웃 타임을 적절한 타임 스탬프로 변환하는 방법에 대한 진정한 질문이 있다고 생각한다. 그런 다음 LAG()를 사용하여 이전의 시간을 가져 와서 현재의 레코드에서 시간을 빼면된다. . 변환 후 Lag()을 사용하여 빼면 황금이됩니다. – JNevill

답변

0

여기에 cte 및 자체 조인을 사용하여 일부 날짜 시간을 생성 한 후의 방법이 나와 있습니다. 당신이 2012 년이기 때문에, 당신이 여기 LEAD를 사용하고 row_number() 기능을 제거 할 수 있습니다 또한

if object_id('tempdb..#Shift') is not null 
drop table #Shift 

CREATE TABLE #Shift(
    FKEmployeeNumber int, 
    DateOfBusiness datetime, 
    FKStoreId int, 
    EmployeeShiftNumber int, 
    FKJobCodeId int, 
    InHour int, 
    InMinute int, 
    OutHour int, 
    OutMinute int) 

insert into #Shift (FKEmployeeNumber, DateOfBusiness, FKStoreId, EmployeeShiftNumber, FKJobCodeId, InHour, InMinute,OutHour,OutMinute) 
values 
(529251, '11/13/2017', 3013, 0, 1, 8, 1, 16, 24), 
(529251, '11/14/2017', 3013, 0, 1, 15, 21, 23, 28), 
(529251, '11/15/2017', 3013, 0, 1, 8, 56, 15, 58), 
(529251, '11/16/2017', 3013, 0, 1, 14, 59, 20, 54), 
(529251, '11/19/2017', 3013, 0, 1, 12, 40, 19, 42), 
(529251, '11/20/2017', 3013, 1, 1, 8, 28, 23, 47), 
(529251, '11/21/2017', 3013, 0, 1, 15, 31, 23, 30), 
(529251, '11/25/2017', 3013, 0, 1, 10, 26, 18, 13), 
(529251, '11/27/2017', 3013, 0, 1, 9, 58, 18, 27), 
(529251, '11/28/2017', 3013, 0, 1, 14, 59, 2, 32), 
(529251, '11/29/2017', 3013, 0, 1, 10, 11, 17, 13), 
(529251, '11/29/2017', 3013, 1, 1, 17, 16, 17, 25), 
(529251, '11/30/2017', 3013, 0, 1, 15,4, 20, 0), 
(529251, '11/30/2017', 3013, 1, 1, 20, 0, 23, 18), 
(529251, '11/30/2017', 3013, 2, 1, 23, 18, 23, 22), 
(529251, '12/01/2017', 3013, 0, 1, 12, 12, 16, 0) 


;with cte as(
select 
    FKEmployeeNumber 
    ,DateOfBusiness 
    ,FKStoreId 
    ,EmployeeShiftNumber 
    ,FKJobCodeId 
    ,clockin = cast(convert(varchar(10),DateOfBusiness,101) + ' ' + right('00' + cast(InHour as varchar),2) + ':' + right('00' + cast(InMinute as varchar),2) as datetime) 
    ,clockout = cast(convert(varchar(10),DateOfBusiness,101) + ' ' + right('00' + cast(OutHour as varchar),2) + ':' + right('00' + cast(OutMinute as varchar),2) as datetime) 
from 
    #Shift), 

cte2 as(
select *, RN = row_number() over (partition by FKEmployeeNumber order by clockin) 
from cte) 

select 
    c.FKEmployeeNumber 
    ,c.DateOfBusiness 
    ,c.FKStoreId 
    ,c.EmployeeShiftNumber 
    ,c.FKJobCodeId 
    ,c.clockin 
    ,c.clockout 
    ,nexClockInHourDifference = datediff(minute,c.clockout,c2.clockin)/60.0 
from cte2 c 
left join cte2 c2 on c2.FKEmployeeNumber = c.FKEmployeeNumber and c2.RN = c.RN + 1 

drop table #Shift 

, ...

;with cte as(
select 
    FKEmployeeNumber 
    ,DateOfBusiness 
    ,FKStoreId 
    ,EmployeeShiftNumber 
    ,FKJobCodeId 
    ,clockin = cast(convert(varchar(10),DateOfBusiness,101) + ' ' + right('00' + cast(InHour as varchar),2) + ':' + right('00' + cast(InMinute as varchar),2) as datetime) 
    ,clockout = cast(convert(varchar(10),DateOfBusiness,101) + ' ' + right('00' + cast(OutHour as varchar),2) + ':' + right('00' + cast(OutMinute as varchar),2) as datetime) 
from 
    #Shift) 


select 
    c.FKEmployeeNumber 
    ,c.DateOfBusiness 
    ,c.FKStoreId 
    ,c.EmployeeShiftNumber 
    ,c.FKJobCodeId 
    ,c.clockin 
    ,c.clockout 
    ,nexClockInHourDifference = datediff(minute,c.clockout,lead(c.clockin) over(partition by FKEmployeeNumber order by clockin))/60.0 
from cte c 

drop table #Shift