Search code examples
sql-serversql-server-2008sql-server-2005sql-server-2008-r2sql-server-ce

Bio-Metric device record


Hi i have get data from bio-metric device like :-

|Id     |EmpCode    | WorkDate                   |InOutMode  
|247    |51         | 2017-02-13 20:08:52.000    |0          
|392    |51         | 2017-02-13 22:38:51.000    |1          
|405    |51         | 2017-02-13 22:59:18.000    |0          
|415    |51         | 2017-02-13 23:18:17.000    |1          
|423    |51         | 2017-02-13 23:33:44.000    |0          
|456    |51         | 2017-02-13 01:30:15.000    |1          
|463    |51         | 2017-02-13 02:52:02.000    |0          
|483    |51         | 2017-02-13 05:11:54.000    |1          
|1034   |51         | 2017-02-14 20:09:23.000    |0          
|1172   |51         | 2017-02-14 21:59:23.000    |1          
|1217   |51         | 2017-02-14 22:30:28.000    |0
|1214   |51         | 2017-02-14 22:30:39.000    |0          
|1238   |51         | 2017-02-14 22:49:51.000    |1          
|1257   |51         | 2017-02-14 23:19:10.000    |0          
|1315   |51         | 2017-02-14 05:04:16.000    |1          
|1323   |51         | 2017-02-14 05:05:17.000    |0          
|1329   |51         | 2017-02-14 05:08:17.000    |1
|1330   |51         | 2017-02-14 05:08:18.000    |1

I want to get data from above table record like:-

|EmpCode   |WorkDate       |CheckIn    |CheckOut   |TotalHours
|51        |2017-02-13     |20:08:52   |22:38:51   |2.499722000
|51        |2017-02-13     |22:59:18   |23:18:17   |0.316388000
|51        |2017-02-13     |23:33:44   |01:30:15   |3.103330000
|51        |2017-02-13     |02:52:02   |05:11:54   |2.331111000
|51        |2017-02-14     |20:09:23   |21:59:23   |1.833333000
|51        |2017-02-14     |22:30:28   |22:49:51   |0.323055000
|51        |2017-02-14     |23:19:10   |05:04:16   |5.323055000
|51        |2017-02-14     |05:05:17   |05:08:18   |0.050000000

PS: The duplicate IN or OUT is ignored.13th,14th,17th and 18th lines in the raw data. 2. Minutes are in decimal point to the hour in the hours calculation.

I need help of the Sql-Server query to use to get these results.

My current code is not help me and also leave some rows and get wrong result and total of hours thanks :)

Note:- When my query excute missing two rows :-

|456    |51         | 2017-02-13 01:30:15.000    |1          
|463    |51         | 2017-02-13 02:52:02.000    |0

Solution

  • Assuming 0 in In and 1 is Out.

    I included an Overnight column to return 1 when CheckOut is on the next day. You can comment it out if you do not need it.

    using cross apply()

    rextester: http://rextester.com/ENFRC28977

    with cte as (
      select 
          Id
        , EmpCode
        , WorkDate
        , InOutMode
        , Lag_InOutMode = Lag(InOutMode) over (order by EmpCode, WorkDate)
      from t
    )
    select 
        i.EmpCode
      , WorkDate = convert(varchar(10),convert(date,i.WorkDate))
      , Overnight = case when datediff(day,i.WorkDate,o.WorkDate)>0 then 1 else 0 end
      , CheckIn  = convert(time,i.WorkDate)
      , CheckOut = convert(time,o.WorkDate)
      , TotalHours = datediff(second,i.WorkDate,o.WorkDate)/3600.0
    from cte i 
    cross apply (
        select top 1 WorkDate
        from cte o
        where o.EmpCode = i.EmpCode
          and o.InOutMode = 1
          and o.Lag_InOutMode != 1
          and o.WorkDate > i.WorkDate
        order by o.WorkDate asc
        ) as o
    where i.InOutMode = 0 
      and i.Lag_InOutMode != 0
    order by i.WorkDate
    

    returns:

    +---------+------------+-----------+----------+----------+------------+
    | EmpCode |  WorkDate  | Overnight | CheckIn  | CheckOut | TotalHours |
    +---------+------------+-----------+----------+----------+------------+
    |      51 | 2017-02-13 |         0 | 02:52:02 | 05:11:54 | 2,331111   |
    |      51 | 2017-02-13 |         0 | 20:08:52 | 22:38:51 | 2,499722   |
    |      51 | 2017-02-13 |         0 | 22:59:18 | 23:18:17 | 0,316388   |
    |      51 | 2017-02-13 |         1 | 23:33:44 | 05:04:16 | 5,508888   |
    |      51 | 2017-02-14 |         0 | 05:05:17 | 05:08:17 | 0,050000   |
    |      51 | 2017-02-14 |         0 | 20:09:23 | 21:59:23 | 1,833333   |
    |      51 | 2017-02-14 |         0 | 22:30:28 | 22:49:51 | 0,323055   |
    +---------+------------+-----------+----------+----------+------------+
    

    I do not see a 0 InOutMode prior to for '2017-02-13 01:30:15', so my results do not contain a row for:

    |51        |2017-02-13     |23:33:44   |01:30:15   |3.103330000