如何查找每位员工的进出时间

时间:2015-04-15 13:16:53

标签: sql-server

鉴于表:

id       time_stamp                  Access Type    
0301    2013-09-05 09:35:00         IN
0302    2013-09-05 11:00:00         IN
0301    2013-09-05 12:00:00         OUT
0302    2013-09-05 12:25:00          OUT
0301    2013-09-05 13:00:00          IN
0302    2013-09-05 14:00:00         IN
0301    2013-09-05 17:00:00          OUT
0302    2013-09-05 18:00:00         OUT

预期产出:

id      first_in    last_out    date           duration(last_out - first_in)
0301    09:35       17:35       2013-09-05          08:00
0302    11:00       18:00       2013-09-05          07:00

我需要在java中为预准备语句提供高效的SQL查询。

2 个答案:

答案 0 :(得分:1)

您可以按idcast(time_stamp as date)进行分组,每人每天创建一行:

select  *
,       datediff(minute, first_in, last_out) as duration
from    (
        select  id
        ,       min(case when [Access Type] = 'IN' then time_stamp end) as first_in
        ,       max(case when [Access Type] = 'OUT' then time_stamp end) as last_out
        ,       cast(min(time_stamp) as date) as date
        from    Table1
        group by
                id
        ,       cast(time_stamp as date)
        ) as SubQueriesMustBeNamed

See it working at SQL Fiddle.

答案 1 :(得分:0)

您可以使用以各种条件将表格连接到自身的查询来过滤InOut

构建样本数据

-- temp table for your sample data
CREATE TABLE #GivenTable
    (
      [id] INT ,
      [time_stamp] DATETIME ,
      [Access Type] VARCHAR(3)
    );
-- insert your sample data        
INSERT  INTO #GivenTable
        ( [id], [time_stamp], [Access Type] )
VALUES  ( 0301, '2013-09-05 09:35:00', 'IN' ),
        ( 0302, '2013-09-05 11:00:00', 'IN' ),
        ( 0301, '2013-09-05 12:00:00', 'OUT' ),
        ( 0302, '2013-09-05 12:25:00', 'OUT' ),
        ( 0301, '2013-09-05 13:00:00', 'IN' ),
        ( 0302, '2013-09-05 14:00:00', 'IN' ),
        ( 0301, '2013-09-05 17:00:00', 'OUT' ),
        ( 0302, '2013-09-05 18:00:00', 'OUT' );

SELECT查询:

SELECT  tIn.id ,
        MIN(tIn.time_stamp) AS FirstIn ,
        MAX(tOut.time_stamp) AS LastOut ,
        CONVERT(DATE, tOut.time_stamp) AS AccessDate ,
        DATEDIFF(MINUTE, 
                 MIN(tIn.time_stamp), 
                 MAX(tOut.time_stamp)) / 60.0 AS DurationInHours
FROM    #GivenTable tIn
    INNER JOIN #GivenTable tOut ON tOut.id = tIn.id
               AND CONVERT(DATE, tOut.time_stamp) = CONVERT(DATE, tIn.time_stamp)
WHERE   tIn.[Access Type] = 'IN'
        AND tOut.[Access Type] = 'OUT'
GROUP BY tIn.id ,
        CONVERT(DATE, tOut.time_stamp)
-- clean up temp table
DROP TABLE #GivenTable

此处的FROM子句在idtime_stamp的日期部分连接到同一个表两次。

WHERE子句指定tIn.[Access Type] = 'IN' AND tOut.[Access Type] = 'OUT'。这意味着tIn中的数据是IN数据,tOutOUT数据。

MINMAX用于获取FirstInLastOut值,DATEDIFF用于计算时差。

GROUP BY使用CONVERT(DATE, tOut.time_stamp)取消日期时间的时间部分,以便将同一天的记录组合在一起。

这假设人们永远不会跨越白天工作/夜班工作。