2013-07-15 2 views
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-й раз для входа .. затем третий и четвёртый раз Войти , Как я могу это сделать, любезно предлагаю решение как можно скорее, спасибо.

+1

который DATATYPE вы используете для столбца входа – Ahmed

ответ

0

Try:

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

Эта разница будет получить в течение нескольких минут

SQLFiddle DEMO

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 
+0

Привет @ БОГДАН-sahlean, спасибо за ваше решение его работает нормально, я JST хочу изменить этот запрос, как если бы это разностное между 1-м и 2-м меньше 5 минут, то разница должна быть рассчитана между 1-м и 3-м остальными 1-го и 4-м. .. hw я могу это сделать .. plz giv solution – shweta

+0

plz предоставить решение – shweta

+0

@shweta: ваш вопрос * найти разницу между 1-м и 2-м регистрационными номерами .. затем 3-й и 4-е время входа *. Теперь вам нужно решение для * другой проблемы/вопроса *. Вы должны создать другой вопрос. Мой ответ - это решение для вашего [внутреннего] вопроса. –

0

Вот полный запрос, который вы можете попробовать использовать. Как уже показал Ненад Зивкович, идея заключается в использовании функции 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 
Смежные вопросы