У меня есть 3 базы данных, которые включают одну и ту же таблицу «acc_monitor_log», такую как идентификатор сотрудника в качестве PIN-кода и время входа, например, вход и выход, пример acc_monitor_log:
time pin state
2020-05-05 08:14:47.000 240 0
2020-05-05 15:32:21.000 240 1
2020-05-06 08:04:32.000 240 0
2020-05-06 08:04:37.000 240 0
2020-05-06 09:39:16.000 240 1
2020-05-06 10:04:17.000 240 0
2020-05-06 15:28:54.000 240 1
где PIN-код - это код сотрудника и состояние 0 - время входа, а 1 - выход
и мы работаем в 3 смены, смена 1 «8 часов» с 8 утра до 4 вечера и смена 2 «8 часов» с 16 до 23 часов. и сдвинуть 3 «9 часов» с 23:00 до 8:00
То, что я пробовал:
declare
@tbl table(pin nvarchar(50),_shift nvarchar(20),_in datetime,_out datetime)
declare
@tblfinal table(serial int,pin nvarchar(50),_shift nvarchar(20),dd int,mm int,_in datetime,_out datetime)
declare
@shift1start time = '06:30:00',
@shift1end time ='20:30:00',
@shift2start time ='13:00:00',
@shift2end time = '09:30:00',
@startdate date = '2020-04-25',
@enddate date = '2020-04-25'
while @startdate != '2020-05-08'
begin
begin
with cte_ as (
SELECT abc.pin ,
(SELECT min(time)
FROM [TUBE1].[dbo].[acc_monitor_log]
where convert(date,time) between @startdate and @enddate and state =0 and pin=abc.pin)_in,
(SELECT max(time) FROM [TUBE1].[dbo].[acc_monitor_log]
where convert(date,time) between @startdate and @enddate
and state = 1 and pin=abc.pin)_out
FROM [TUBE1].[dbo].[acc_monitor_log] abc
where convert(date,time) between @startdate and @enddate
group by pin)
,
cte_2 as (
SELECT abc.pin ,
--min(time) _in,
(SELECT min(time)
FROM [TUBE2].[dbo].[acc_monitor_log]
where convert(date,time) between @startdate and @enddate
and state =1
and pin=abc.pin)_in,
(SELECT max(time)
FROM [TUBE2].[dbo].[acc_monitor_log]
where convert(date,time) between @startdate and @enddate
and state = 0
and pin=abc.pin)_out
FROM [TUBE2].[dbo].[acc_monitor_log] abc
where convert(date,time) between @startdate and @enddate
group by pin),
--order by pin asc
cte_3 as (
SELECT abc.pin ,
--min(time) _in,
(SELECT min(time)
FROM [TUBE3].[dbo].[acc_monitor_log]
where convert(date,time) between @startdate and @enddate
and state =0
and pin=abc.pin)_in,
--max(time) _out
(SELECT max(time)
FROM [TUBE3].[dbo].[acc_monitor_log]
where convert(date,time) between @startdate and @enddate
and state = 1
and pin=abc.pin)_out
FROM [TUBE3].[dbo].[acc_monitor_log] abc
where convert(date,time) between @startdate and @enddate
--and min(time) having state=0
--and pin=10
group by pin)
--order by pin asc
insert into @tbl
select cte_.pin,
case
when convert(time,cte_._in) between @shift1start and @shift1end
and convert(time,cte_._out) between @shift1start and @shift1end then '1'
when convert(time,cte_._in) between @shift2start and @shift2end
and convert(time,cte_._out) between @shift2start and @shift2end then '2'
else 'unkown'
end as _sift,
cte_._in,cte_._out
from cte_
union
select cte_2.pin,
case
when convert(time,cte_2._in) between @shift1start and @shift1end
and convert(time,cte_2._out) between @shift1start and @shift1end then '1'
when convert(time,cte_2._in) between @shift2start and @shift2end
and convert(time,cte_2._out) between @shift2start and @shift2end then '2'
else 'unkown'
end as _sift,
cte_2._in,cte_2._out
from cte_2
union
select cte_3.pin,
case
when convert(time,cte_3._in) between @shift1start and @shift1end
and convert(time,cte_3._out) between @shift1start and @shift1end then '1'
when convert(time,cte_3._in) between @shift2start and @shift2end
and convert(time,cte_3._out) between @shift2start and @shift2end then '2'
else 'unkown'
end as _sift,
cte_3._in,cte_3._out
from cte_3
order by pin
end
set @startdate = dateadd(day,1,@startdate)
set @enddate = dateadd(day,1,@enddate)
end
declare @pinn int = 0
while @pinn <=600
begin
insert into @tblfinal
select row_number() over (partition by dd,mm order by dd,mm)as serial,* from
(select pin,_shift,datepart(day,_in) dd,datepart(MONTH,_in) mm,_in,_out from @tbl )a
where pin = @pinn
set @pinn = @pinn+1
end
select pin,_shift,min(_in) _in_,max(_out) _out_ from
(
select RIGHT('0000'+ISNULL(pin,''),4) as pin,_shift,_in,convert(date,_in)datein,_out ,convert(date,_out) dateout
from @tblfinal
where serial = 1
)aa
where (datein = dateout or dateout = dateadd(day,1,datein) or datein is null or dateout is null)
group by pin,_shift,case when datein is not null then datein else dateout end
order by pin
, но я получил результат с множеством значений NULL и не t получить правильное время
0006 1 2020-04-26 14:53:54.000 2020-04-26 08:08:03.000
0006 1 2020-05-03 14:52:24.000 2020-05-03 07:59:05.000
0006 unkown 2020-04-25 14:59:34.000 NULL
0006 unkown NULL 2020-04-27 07:54:17.000
0006 unkown 2020-05-02 15:10:04.000 NULL
0006 unkown 2020-05-06 15:04:28.000 NULL