2016-03-29 4 views
1

У меня есть следующий запрос, где намерение состоит в том, чтобы показать каждую запись со временем до следующей записиSQL «Где В» для пустого подзапроса

данные:

gid   time    name 
1010883478 29/03/2016 0:00:02 John 
1010883527 29/03/2016 0:00:04 John 
1010883578 29/03/2016 0:00:06 John 

SQL:

SELECT A.[gid] 
     ,A.[time] 
     ,A.[name] 
     ,(B.[time] - A.[time]) as timeTilNext 
    FROM [location] A CROSS JOIN [location] B 
    WHERE B.[gid] IN (
     SELECT MIN(C.[gid]) 
     FROM [location] C 
     WHERE C.[gid] > A.[gid] AND C.[name] = A.[name]) 
    ORDER BY A.[gid] 

Выходной ток:

gid   time     name timeTilNext 
1010883478 2016-03-29 00:00:02.000 John 1900-01-01 00:00:02.000 
1010883527 2016-03-29 00:00:04.000 John 1900-01-01 00:00:02.000 

Ожидаемый результат:

gid   time     name timeTilNext 
1010883478 2016-03-29 00:00:02.000 John 1900-01-01 00:00:02.000 
1010883527 2016-03-29 00:00:04.000 John 1900-01-01 00:00:02.000 
1010883578 2016-03-29 00:00:06.000 John -1 (or whatever) 

Однако, он не показывает запись для самого высокого [GID] для данного [имя] (только второй самый высокий).

Я надеюсь на высший [gid], чтобы показать -1 для timeTilNext, чтобы указать, что событий больше нет.

Есть идеи по изменению моего запроса?

+1

пожалуйста, после некоторых выборочных данных и ожидаемого результата. Какую версию SQL Server вы используете? – Squirrel

+0

@Squirrel сделано! – Zeophlite

+0

Неужели почему удаленные и почему ответы были удалены? – Zeophlite

ответ

2

В SQL Server 2012 можно использовать LEAD функцию окна, чтобы получить значение «следующий» ряд.

DECLARE @location TABLE ([gid] int, [time] datetime, [name] varchar(50)); 

INSERT INTO @location ([gid], [time], [name]) VALUES 
(1010883478, '2016-03-29 00:00:02', 'John'), 
(1010883527, '2016-03-29 00:00:04', 'John'), 
(1010883578, '2016-03-29 00:00:06', 'John'); 

SELECT 
    A.[gid] 
    ,A.[time] 
    ,A.[name] 
    ,LEAD(A.[time]) OVER(PARTITION BY A.[name] ORDER BY A.[gid]) AS NextTime 
    ,ISNULL(DATEDIFF(second, A.[time], 
     LEAD(A.[time]) OVER(PARTITION BY A.[name] ORDER BY A.[gid])), -1) AS SecondsTillNext 
FROM @location A 
ORDER BY A.[gid]; 

Результат

+------------+-------------------------+------+-------------------------+-----------------+ 
| gid  |   time   | name |  NextTime   | SecondsTillNext | 
+------------+-------------------------+------+-------------------------+-----------------+ 
| 1010883478 | 2016-03-29 00:00:02.000 | John | 2016-03-29 00:00:04.000 |    2 | 
| 1010883527 | 2016-03-29 00:00:04.000 | John | 2016-03-29 00:00:06.000 |    2 | 
| 1010883578 | 2016-03-29 00:00:06.000 | John | NULL     |    -1 | 
+------------+-------------------------+------+-------------------------+-----------------+ 

Если "следующая" строка отсутствует, LEAD вернется NULL. Вы можете использовать ISNULL(), чтобы заменить его некоторым ненулевым значением, если хотите.

0
select 
*,-1 as 'time until next ' from location t1 
where time=(select max(time) from location t2 where t1.name=t2.name) b 
+0

Не могли бы вы обновить это, чтобы соответствовать заголовкам в вопросе? – Zeophlite

+0

Это соответствует заголовкам вашего вопроса, только изменение - это имя_таблицы, я изменил его сейчас – TheGameiswar

0

SELECT A.gid, A.name, A.time, ( (SELECT MIN (B.time) FROM [location] B WHERE B.time> A.time AND B. name = A.name) - A.time ), как timeTilNext

FROM [местоположение] A