我有时间和出勤时钟系统的交易数据,我必须计算区域中的总小时数。所以我使用row over partition创建了一个查询来执行此操作。
如果用户正确使用他们的时钟卡(意味着方向遵循例如in,out,in,out..etc),它可以正常工作。但是因为我们总是不能依赖用户这样做,我们得到这样的数据:
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(Time In Zone)方向之间的时间。
关于如何做到这一点的任何想法?
提前致谢
答案 0 :(得分: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
这是一种做法。我已经猜到了如何处理丢失的数据,但可以根据需要进行更新。
我理解这可能是伪表名,但是可能值得注意的是,使用保留的T-SQL单词是不好的形式,如果可能的话你应该考虑组合日期和时间列。