我想找到同一员工组中同一列的时间数据之间的差异。我写了一个查询如下:
WITH rows AS
(
SELECT isnull(left(hhmm,2)+ ':'+ right(left(hhmm,4),2),'''') as login,
ROW_NUMBER() OVER (ORDER BY cardno) AS rn
FROM ATTN01072013_copy13_7_13
)
SELECT *--mc.login-mp.login as diff
FROM rows mc
JOIN rows mp
ON mc.rn = mp.rn - 1
此查询将返回如下数据:
cardno login rn cardno login rn
E44920 09:18 1 E44920 09:46 2
E44920 09:46 2 E44920 17:09 3
E44920 17:09 3 E44920 16:57 4
E44920 16:57 4 E44920 17:34 5
E44920 17:34 5 E44920 17:53 6
E44920 17:53 6 E44920 17:56 7
E44920 17:56 7 E44920 17:57 8
E44920 17:57 8 E44920 18:00 9
现在我想找到第1和第2次登录时间之间的差异..然后第3和第4次登录时间。我怎么能这样做,请尽快建议解决方案,谢谢。
答案 0 :(得分:2)
解决方案:
DECLARE @Event TABLE(
EventID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
CardNo VARCHAR(10) NOT NULL,
[Login] DATETIME NOT NULL
-- To prevent duplicate events
-- This constraint will create an index used to optimize the RowNum and the last queries
UNIQUE(CardNo,[Login])
);
INSERT INTO @Event(CardNo,[Login])
SELECT 'E44920', '2013-07-15T09:18:00'
UNION ALL SELECT 'E44920', '2013-07-15T09:46:00'
UNION ALL SELECT 'E44920', '2013-07-15T17:09:00'
UNION ALL SELECT 'E44920', '2013-07-15T16:57:00'
UNION ALL SELECT 'E44920', '2013-07-15T17:34:00'
UNION ALL SELECT 'E44920', '2013-07-15T17:53:00';
DECLARE @EventWithRowNum TABLE(
RowNum INT NOT NULL,
CardNo VARCHAR(10) NOT NULL,
PRIMARY KEY (CardNo,RowNum),
[Login] DATETIME NOT NULL
UNIQUE(CardNo,[Login])
);
INSERT INTO @EventWithRowNum (CardNo,[Login],RowNum)
SELECT e.CardNo, e.[Login], ROW_NUMBER() OVER(PARTITION BY e.CardNo ORDER BY e.[Login]) AS RowNum
FROM @Event e;
-- Final query
SELECT crt.RowNum,
crt.CardNo,
crt.[Login] AS CurrentLogin,
nxt.RowNum,
nxt.[Login] AS NextLogin,
DATEDIFF(SECOND, crt.Login, nxt.Login) AS Diff_Seconds
FROM @EventWithRowNum crt -- crt = odd rows
LEFT JOIN @EventWithRowNum nxt ON crt.CardNo=nxt.CardNo AND crt.RowNum=nxt.RowNum-1 -- nxt = even rows
WHERE crt.RowNum % 2 = 1 -- odd rows; you could add a computed column Modulo2 AS (RowNum % 2) PERSISTED and then you could define a index (key: Modulo2, CardNo, Login)
ORDER BY crt.CardNo, crt.[Login];
结果:
RowNum CardNo Current_Login RowNum Next_Login Diff_Seconds
----------- ---------- ----------------------- ----------- ----------------------- ------------
1 E44920 2013-07-15 09:18:00.000 2 2013-07-15 09:46:00.000 1680
3 E44920 2013-07-15 16:57:00.000 4 2013-07-15 17:09:00.000 720
5 E44920 2013-07-15 17:34:00.000 6 2013-07-15 17:53:00.000 1140
答案 1 :(得分:0)
尝试:
DATEDIFF (mi, CAST(mc.login AS DATETIME), CAST(mp.login AS DATETIME)) as diff
这会在几分钟内产生差异
答案 2 :(得分:0)
以下是您可以尝试使用的完整查询。正如Nenad Zivkovic已经表明的那样,想法是使用DATEDIFF函数。
唯一不同的是,我建议使用完整日期时间计算差异,以避免在一次登录如22:03而另一次登记为00:16时可能出现的问题。
WITH rows AS
(
SELECT isnull(left(hhmm,2)+ ':'+ right(left(hhmm,4),2),'''') as login,
hhmm as Full_Login,
ROW_NUMBER() OVER (ORDER BY cardno) AS rn
FROM ATTN01072013_copy13_7_13
)
SELECT mc.login,
mc.rn,
DATEDIFF(mi,mc.Full_Login, mp.Full_Login)
mp.login,
mc.rn
FROM rows mc
JOIN rows mp
ON mc.rn = mp.rn