2015-10-05 2 views
1

У меня есть таблица, в которой столбцы:разница Рассчитать между двумя отметками в SQL в той же таблице

ID UserId Serial ModifiedDate 
---- ------ ----- ---------------- 

Мне нужно, чтобы вычислить де разницу между отметкой времени из каждой строки. Например, если у меня есть таблица вроде этого:

ID UserId Serial ModifiedDate 
---- ------ ----- ---------------- 
001 1  1111 2015-07-20 10:56:53.0000000 
002 1  1111 2015-07-21 18:49:24.0000000 
003 1  1111 2015-07-22 08:49:23.0000000 

мне нужно сделать разницу между отметкой времени от 001 до 002, затем от 002 и 003, и результат должны быть как:

ID UserId Serial ModifiedDate    Difference 
---- ------ ----- ----------------    -------- 
001 1  1111 2015-07-20 10:56:53.0000000 
002 1  1111 2015-07-21 18:49:24.0000000 
003 1  1111 2015-07-22 08:49:23.0000000 

Я пытаюсь работать с курсорами, чтобы сделать это, но я не мог найти способ получить результат в новом столбце псевдонима.

Это мой запрос:

DECLARE @id bigint, @lastmodif datetime2(7), @id2 bigint, @lastmodif2 datetime2(7),@total int; 

DECLARE status_cursor CURSOR FOR 

SELECT [Id], [ModifiedDate], '0' AS Difference 
FROM [Registrations] 
    where p.Serial = 1111 
    Order by ModifiedDate 

OPEN status_cursor 

DECLARE status_cursor2 CURSOR FOR 

SELECT [Id], [ModifiedDate],'0' AS Difference 
FROM [Registrations] 
    where p.Serial = 1111 
    Order by ModifiedDate 

OPEN status_cursor2 

FETCH NEXT FROM status_cursor2 

WHILE @@FETCH_STATUS = 0 
BEGIN 
FETCH NEXT FROM status_cursor INTO @regid, @lastmodif 
FETCH NEXT FROM status_cursor2 INTO @regid2, @lastmodif2 
SET @total = 
     (
      DATEDIFF(second,@lastmodif,@lastmodif2) 
     ) 
UPDATE status_cursor SET Result = @total 
+0

какая версия сервера sql? –

+0

версия 2012 11.0.5532.0 – juanfandres

+2

lookup LEAD и LAG –

ответ

1

для SQL Server 2008 и выше

with cte as 
(
    select 1 as Id , 1 as UserID, 1111 as Serial, ' 2015-07-20 10:56:53.0000000' as ModifiedDate 
    union all 
    select 
    002, 1,  1111 , '2015-07-21 18:49:24.0000000' 
    union all 
    select 
    003, 1,  1111, '2015-07-22 08:49:23.0000000' 
) 
, 
cte2 as (
select *, 
     (select min(ModifiedDate) from cte as nextRow where nextRow.Serial = cte.Serial and nextRow.Id > cte.Id) as NextModifiedDate 

    from 
    cte 
) 
select id,USERid,Serial,ModifiedDate,DATEDIFF(SECOND,ModifiedDate,isnull(NextModifiedDate,ModifiedDate)) as Difference 
from cte2 

Кроме того, вы можете использовать это непосредственно с таблицей

select * 
      -- ,(select min(ModifiedDate) from Registrations as nextRow where nextRow.Serial = Registrations.Serial and nextRow.Id > Registrations.Id) as NextModifiedDate 
      , DATEDIFF(second,Registrations.ModifiedDate, 
         isnull((select min(ModifiedDate) from Registrations as nextRow where nextRow.Serial = Registrations.Serial and nextRow.Id > Registrations.Id),Registrations.ModifiedDate) 
         ) as Difference 
     from 
     Registrations 
+0

также, вы можете использовать этот \t выбрать * \t \t \t - (выберите мин (ModifiedDate) с регистрациями в nextRow где nextRow.Serial = Registrations.Serial и nextRow.Id> Registrations.Id) в NextModifiedDate \t \t \t , DATEDIFF (второй, Registrations.ModifiedDate, \t \t \t \t \t \t IsNull ((выбрать мин (ModifiedDate) от регистраций как nextRow, где nextRow.Serial = Registrations.Serial и nextRow.Id> Registrations.Id), Registrations.ModifiedDate) \t \t \t \t \t) как разница \t \t от \t \t регистраций –

+0

Я пытался использовать запрос непосредственно в таблице, но когда у меня есть разница между 2 меткой временем, как это: 2015-07-22 08: 49: 23,0000000 - 2015- 07-22 08:50:08.0000000 У меня есть отрицательная разница и не является репрезентативным число – juanfandres

+0

. Я решил проблему с отрицательной разницей. Теперь у меня проблема, когда у меня есть 2 равных меткам времени. В разностном столбце у меня есть одинаковое число. Например: у меня эти 3 строки 2015-07-26 22: 42: 03.0000000/2015-07-26 22: 42: 03.0000000/2015-07-27 07: 07: 16.0000000. Как видите, первые 2 равны, поэтому в разностном столбце у меня одинаковое число для первых 2, что является разницей между 2-й и 3-й. – juanfandres

2

В соответствии с вашим комментарием , ваша версия SQL Server - 2012. Таким образом, вы можете сделать это LEAD()

Вам нужно заменить HH с желаемым значением

SELECT ID, 
     UserId, 
     Serial, 
     ModifiedDate, 
     DATEDIFF(HH,ModifiedDate,LEAD(ModifiedDate) over(ORDER BY ID)) AS [Difference] 
FROM Times 

Try ниже запроса, если LAG() не работает на вашей БД из-за проблем с конфигурацией.

WITH CTE AS 
(
    SELECT *,ROW_NUMBER() OVER(ORDER BY CAST(ID AS INT)) AS RN 
    FROM times 
) 

SELECT C1.*,DATEDIFF(HH,C1.MODIFIEDDATE,C2.MODIFIEDDATE) AS [DIFFERENCE] 
FROM CTE C1 LEFT JOIN CTE C2 ON C1.RN+1 = C2.RN 
+0

@MitchWheat: Спасибо! OP подтвердил версию как 2012 в комментариях. – DarkKnight

+1

Он сделал. Потому что я спросил! ;) –

+0

Я попытался использовать LEAD, но у меня есть это сообщение: функции Parallel Data Warehouse (PDW) не включены. – juanfandres

0

Это работает в течение 2008 года и отличается большей разницей в секундах.

WITH cte AS (SELECT ID, ModifiedDate, 
    DENSE_RANK() OVER (ORDER BY ID ASC) AS Ranking from Registrations), 

SELECT cte1.ID, cte1.ModifiedDate, 
    DATEDIFF(ss, cte1.ModifiedDate, cte2.ModifiedDate) AS TimeDiff 
    FROM cte cte1, cte cte2 
    WHERE cte1.Ranking = cte2.Ranking - 1