2013-05-07 44 views
1

我有我们的时间和考勤计时系统的交易数据,我必须计算区域中的总小时数。所以我使用row over partition创建了一个查询来做到这一点。交易方向Row Over Partition minipulation

如果用户正确使用他们的时钟卡(这意味着方向跟在例如进入,出,进,出......等等),它工作正常。但是因为我们不能总是依靠用户这样做,我们得到的数据是这样的:

MSTSQ DATE  DIRECTION TIME 
----- ---------- --------- ------------ 
61  2013-03-12 IN   07:56:43.000 
61  2013-03-12 OUT   09:58:19.000 
61  2013-03-12 IN   10:16:05.000 
61  2013-03-12 OUT   12:08:10.000 
61  2013-03-12 OUT   12:08:11.000 
61  2013-03-12 IN   12:08:11.000 
61  2013-03-12 IN   12:11:04.000 
61  2013-03-12 OUT   13:45:28.000 
61  2013-03-12 IN   13:45:29.000 
61  2013-03-12 IN   13:50:38.000 
61  2013-03-12 OUT   16:28:11.000 
61  2013-03-12 IN   16:28:12.000 

我的SQL语句的工作方式如下:

WITH TIME_LIST 
AS(
SELECT ROW_NUMBER() OVER (PARTITION BY TD.MSTSQ, TD.DATE ORDER BY TD.ID) RN 
     , TD.MSTSQ 
     , TD.DATE 
     , TD.DIRECTION 
     , TD.TIME 
FROM TRANSACK_DETAILS TD 
) 

Select 
    currul.MSTSQ 
, currul.DATE 
, Convert(datetime, prevul.TIME - currul.TIME,108) [Time In Zone] 
FROM TRANSACTIONS 
INNER JOIN TIME_LIST currul ON currul.MSTSQ = TRANSACTIONS.MST_SQ 
    AND TRANSACTIONS.EVENT_DATE = currul.DATE 
INNER JOIN TIME_LIST prevul ON currul.MSTSQ = prevul.MSTSQ 
    AND currul.DATE = prevul.DATE AND currul.Rn+1 = prevul.Rn 

我的结果,那么看起来是这样的:

MSTSQ DATE  Time In Zone 
----- -------- ------------ 
61  20130312 02:01:36.000 
61  20130312 00:17:46.000 
61  20130312 01:52:05.000 
61  20130312 00:00:01.000 
61  20130312 00:00:00.000 
61  20130312 00:02:53.000 
61  20130312 01:34:24.000 
61  20130312 00:00:01.000 
61  20130312 00:05:09.000 
61  20130312 02:37:33.000 
61  20130312 00:00:01.000 

现在我需要更改语句以仅计算IN和OUT(时区)方向之间的时间。

有关如何做到这一点的任何想法?

在此先感谢

回答

1
select tin.MSTSQ 
    , [DATE] = tin.[DATE] 
    , INTIME = tin.[TIME] 
    , OUTTIME = tout.[TIME] 
    , DURATION = datediff(ss, tin.[TIME], tout.[TIME]) 
from times tin 
    outer apply (select top 1 * 
       from times tout 
       where tin.MSTSQ = tout.MSTSQ 
       and tin.[DATE] = tout.[DATE] 
       and tin.[TIME] < tout.[TIME] 
       order by tout.[TIME]) tout 
where tin.DIRECTION = 'IN' 
    and (tout.DIRECTION IS NULL or tout.DIRECTION = 'OUT') 
order by tin.MSTSQ 

SQL Fiddle with demo

下面介绍一种方法。我曾猜测如何处理缺失的数据,但可以根据需要进行更新。

我知道这可能是伪表名,但可能值得注意的是,使用保留的T-SQL字是不好的形式,如果可能的话,您应该考虑组合日期和时间列。

+0

你先生是一个绅士和学者。谢谢你的帮助。 – 2013-05-07 09:18:56

+0

天哪,非常感谢! – 2013-05-07 09:22:44