2

我想找到同一员工组同一列中的时间数据之间的差异。我写了一个查询如下:

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 次登录时间。我该怎么做,请尽快提出解决方案,谢谢。

4

3 回答 3

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
于 2013-07-15T10:00:40.107 回答
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  
于 2013-07-15T13:07:14.623 回答
0

Try:

DATEDIFF (mi, CAST(mc.login AS DATETIME), CAST(mp.login AS DATETIME)) as diff

This will get difference in minutes

SQLFiddle DEMO

于 2013-07-15T07:19:25.667 回答