用列来检查某人是否缺席

时间:2014-01-22 11:10:38

标签: sql sql-server tsql sql-server-2012

我已根据Intime和outTime编写查询来计算员工的总工作时间和加班时间,但无法计算出另一列“IsAbsent”。例如如果人没有来自他的INtime和TimeOut之前的任何特定日期,那么如果两者都是空的那么新列IsAbsent应该包含ABSENT,否则如果两者都填充而不是现在。

查询:

with times as (
SELECT    t1.EmplID
        , t3.EmplName
        , min(t1.RecTime) AS InTime
        , max(t2.RecTime) AS [TimeOut]
        , cast(min(t1.RecTime) as datetime) AS InTimeSub
        , cast(max(t2.RecTime) as datetime) AS TimeOutSub
        , t1.RecDate AS [DateVisited]
FROM  AtdRecord t1 
INNER JOIN 
      AtdRecord t2 
ON    t1.EmplID = t2.EmplID 
AND   t1.RecDate = t2.RecDate
AND   t1.RecTime < t2.RecTime
inner join 
      HrEmployee t3 
ON    t3.EmplID = t1.EmplID 
group by 
          t1.EmplID
        , t3.EmplName
        , t1.RecDate
)
SELECT EmplID
,EmplName
,InTime
,[TimeOut]
,[DateVisited]
,convert(char(5),cast([TimeOutSub] - InTimeSub as time), 108) totaltime
,convert(char(5), case when TimeOutSub - InTimeSub >= '08:01' then 
cast(TimeOutSub - dateadd(hour, 8, InTimeSub) as time) else '00:00' end, 108) as overtime
FROM times

输出:

enter image description here

2 个答案:

答案 0 :(得分:1)

试试这个,我不确定它是否有效,但值得一试(它在我脑海中起作用):

WITH times as (
SELECT    t3.EmplID
        , t3.EmplName
        , min(t1.RecTime) AS InTime
        , max(t2.RecTime) AS [TimeOut]
        , cast(min(t1.RecTime) as datetime) AS InTimeSub
        , cast(max(t2.RecTime) as datetime) AS TimeOutSub
        , xx.RecDate AS [DateVisited]
        , CASE WHEN max(t1.EmplID) is null and max(t2.EmplID) is NULL 
                      then 'Yes' else 'No' END IsAbsent
FROM  HrEmployee t3 
CROSS JOIN
(SELECT DISTINCT RecDate FROM AtdRecord) xx
LEFT JOIN  AtdRecord t1 
ON    t3.EmplID = t1.EmplID 
      and t1.RecDate = xx.RecDate
LEFT JOIN
      AtdRecord t2 
ON    t3.EmplID = t2.EmplID 
AND   t1.RecDate = t2.RecDate
AND   t1.RecTime < t2.RecTime
AND   t2.RecDate = xx.RecDate
group by 
          t3.EmplID
        , t3.EmplName
        , xx.RecDate
)
SELECT EmplID
,EmplName
,InTime
,[TimeOut]
,[DateVisited]
,convert(char(5),cast([TimeOutSub] - InTimeSub as time), 108) totaltime
,convert(char(5), case when TimeOutSub - InTimeSub >= '08:01' then 
cast(TimeOutSub - dateadd(hour, 8, InTimeSub) as time) else '00:00' end, 108) as overtime,
isAbsent
FROM times

答案 1 :(得分:0)

-- Change the order of join start with employee and left outer join with rest of the     tables and calculate time ; I tried to make it for you (fix if anything left); 
with times as (
SELECT    t1.EmplID
    , t3.EmplName
    , min(ISNULL(t1.RecTime,0)) AS InTime
    , max(ISNULL(t2.RecTime,0)) AS [TimeOut]
    , cast( min(ISNULL(t1.RecTime,0)) as datetime) AS InTimeSub
    , cast(max(ISNULL(t2.RecTime,0))  as datetime) AS TimeOutSub
    , t1.RecDate AS [DateVisited]
FROM  HrEmployee t3 
LEFT OUTER JOIN 
AtdRecord t1 ON    t1.EmplID = t3.EmplID
LEFT OUTER JOIN 
  AtdRecord t2 
ON    t1.EmplID = t2.EmplID 
AND   t1.RecDate = t2.RecDate
AND   t1.RecTime < t2.RecTime
group by 
      t1.EmplID
    , t3.EmplName
    , t1.RecDate
)
SELECT EmplID
,EmplName
,InTime
,[TimeOut]
,[DateVisited]
,convert(char(5),cast([TimeOutSub] - InTimeSub as time), 108) totaltime
,convert(char(5), case when TimeOutSub - InTimeSub >= '08:01' then 
cast(TimeOutSub - dateadd(hour, 8, InTimeSub) as time) else '00:00' end, 108) as         overtime,
CASE WHEN InTimeSub = TimeOutSub Then 'Absent'
Else 'Present'   End As Attendance
FROM times