鉴于表:
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查询。
答案 0 :(得分:1)
您可以按id
和cast(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
答案 1 :(得分:0)
您可以使用以各种条件将表格连接到自身的查询来过滤In
和Out
。
构建样本数据
-- 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
子句在id
和time_stamp
的日期部分连接到同一个表两次。
WHERE
子句指定tIn.[Access Type] = 'IN' AND tOut.[Access Type] = 'OUT'
。这意味着tIn
中的数据是IN
数据,tOut
是OUT
数据。
MIN
和MAX
用于获取FirstIn
和LastOut
值,DATEDIFF
用于计算时差。
GROUP BY
使用CONVERT(DATE, tOut.time_stamp)
取消日期时间的时间部分,以便将同一天的记录组合在一起。
这假设人们永远不会跨越白天工作/夜班工作。