【问题标题】:Find difference between rows of same column (difference between time data)查找同一列的行之间的差异(时间数据之间的差异)
【发布时间】:2013-07-12 23:14:15
【问题描述】:

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

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

【问题讨论】:

  • 您用于列登录的数据类型

标签: asp.net sql sql-server datetime time


【解决方案1】:

解决方案:

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

【讨论】:

  • 嗨@bogdan-sahlean,感谢您的解决方案工作正常,我只想修改这个查询,好像第一个和第二个之间的差异小于5分钟,那么应该计算第一个之间的差异和第 3 次第 1 次和第 4 次 ..so 我能做到这一点..plz giv 解决方案
  • @shweta:您的问题是找出第 1 次和第 2 次登录时间之间的差异......然后是第 3 次和第 4 次登录时间。现在您想要另一个问题/问题的解决方案。您应该创建另一个问题。我的回答是为您的 [初始] 问题提供解决方案。
【解决方案2】:

试试:

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

这将在几分钟内产生差异

SQLFiddle DEMO

【讨论】:

    【解决方案3】:

    这是您可以尝试使用的完整查询。正如 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  
    

    【讨论】:

      猜你喜欢
      • 2018-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多