比较两个表并选择表1中不存在的值(基于时间)

时间:2017-02-16 08:30:19

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

我有如下表格:

TimeIn      TimeOut
-------------------
07:30       12:30
13:30       16:30

我有如下表二:

TimeIn      TimeOut
-------------------
07:00       07:06
07:10       08:30
08:45       12:45
13:55       15:30
16:15       16:50

表1是员工的轮班政策,表2是员工的出勤时间。

我想知道这名员工在轮班政策时间外的时间安排?

预期输出:

TimeIn      TimeOut
-------------------
08:30       08:45
13:30       13:55
15:30       16:15

我正在尝试的查询无效:

SELECT InTime AS TimeIn, OutTime AS TimeOut FROM HR.GetRegisterList(@EmpId, @Date)
EXCEPT
SELECT FromTime AS TimeIn, ToTime AS TimeOut FROM HR.GetEmployeeDateShiftDetails(@EmpId, @Date)

1 个答案:

答案 0 :(得分:0)

以下代码段应该完成工作,我必须在Shift Policy table中进行修改 - 添加了column ShiftType -

declare @shiftpolicy table(time_in varchar(10),time_out varchar(10),ShiftType NVARCHAR(2))
insert into @shiftpolicy values ('07:30','12:30','M'),('13:30','16:30','A')
declare @attendance table(time_in varchar(10),time_out varchar(10))
insert into @attendance values ('07:00','07:06'),('07:10','08:30'),('08:45','12:45'),('13:55','15:30'),('16:15','16:50')
select * from @shiftpolicy
select * from @attendance
SELECT * FROM
(
    select case 
                when row = 1 then 
                    case when time_in > DefTimeIn then DefTimeIn--+' - '+convert(nvarchar(50),time_in)
                    else ''
                    end
                when row = last
                    then case when time_out < DefTimeOut then time_out--+' - '+convert(nvarchar(50),DefTimeOut)
                    else ''
                    end
                else ''
                    end--*
            [Out]
                ,case 
                when row = 1 then 
                    case when time_in > DefTimeIn then time_in
                    else ''
                    end
                when row = last
                    then case when time_out < DefTimeOut then DefTimeOut
                    else ''
                    end
                else ''
                    end--,*
                [IN]
    --select *
    from 
    (
        select last_value(row) over (partition by ShiftType order by ShiftType) last ,*
        from 
        (
            select ts.time_in DefTimeIn,ts.time_out DefTimeOut,ts.ShiftType,ta.*,ROW_NUMBER() OVER(PARTITION BY ts.time_in,ShiftType ORDER BY ta.time_in) row
                ,lead(ta.time_in,1,0) over (PARTITION BY ts.time_in,ShiftType ORDER BY ta.time_in) TimeOt
            from @shiftpolicy ts
            inner join @attendance ta 
                on ta.time_in <= ts.time_out and ta.time_out >= ts.time_in
        )t
    )ta
    --order by ShiftType desc

    union

    select time_out,lead from
    (
        select ts.time_in DefTimeIn,ts.time_out DefTimeOut,ts.ShiftType,ta.*,ROW_NUMBER() OVER(PARTITION BY ts.time_in,ShiftType ORDER BY ta.time_in) row
            ,lead(ta.time_in,1,0) over (PARTITION BY ts.time_in,ShiftType ORDER BY ta.time_in) lead
            --,lag(ta.time_in,1,0) over (PARTITION BY ts.time_in,ShiftType ORDER BY ta.time_in)
            --,last_value(ta.time_out) over(PARTITION BY ts.time_in,ShiftType ORDER BY shiftType)
        from @shiftpolicy ts
        inner join @attendance ta 
            on ta.time_in <= ts.time_out and ta.time_out >= ts.time_in
    )t
)TA
where ([OUT] <> '1900-01-01 00:00:00.000' AND [IN] <> '1900-01-01 00:00:00.000') AND [out] <> '' AND [in] <> '0'
order by 1