У меня есть таблица SQL Server со столбцом "Время". Таблица представляет собой таблицу журнала сообщений о статусах домов и временных меток для каждого сообщения. Таблица журналов вставляется через пакетный файл. Существует столбец идентификатора, который группирует строки вместе. Каждый раз, когда запущен командный файл, он инициализирует идентификатор и записывает записи. Что мне нужно сделать, так это получить прошедшее время из первой записи в идентификаторе, установленном на последнюю запись того же набора идентификаторов. Я начал играть с select Max (Time) - Min (Time) из logTable, где id =, но не мог понять, как правильно его отформатировать. Мне это нужно в HH: MM: SS.
SQL Server - вычисляет прошедшее время между двумя штампами datetime в формате HH: MM: SS
Ответ 1
SQL Server не поддерживает тип данных стандартного интервала SQL. Лучше всего рассчитать разницу в секундах и использовать функцию для форматирования результата. Нативная функция CONVERT() может работать нормально, если ваш интервал составляет менее 24 часов. Но CONVERT() не является хорошим решением для этого.
create table test (
id integer not null,
ts datetime not null
);
insert into test values (1, '2012-01-01 08:00');
insert into test values (1, '2012-01-01 09:00');
insert into test values (1, '2012-01-01 08:30');
insert into test values (2, '2012-01-01 08:30');
insert into test values (2, '2012-01-01 10:30');
insert into test values (2, '2012-01-01 09:00');
insert into test values (3, '2012-01-01 09:00');
insert into test values (3, '2012-01-02 12:00');
Значения были выбраны таким образом, что для
- id = 1, прошедшее время - 1 час
- id = 2, прошедшее время составляет 2 часа, а
- id = 3, прошедшее время - 3 часа.
Этот оператор SELECT включает в себя один столбец, который вычисляет секунды, и тот, который использует CONVERT() с вычитанием.
select t.id,
min(ts) start_time,
max(ts) end_time,
datediff(second, min(ts),max(ts)) elapsed_sec,
convert(varchar, max(ts) - min(ts), 108) do_not_use
from test t
group by t.id;
ID START_TIME END_TIME ELAPSED_SEC DO_NOT_USE
1 January, 01 2012 08:00:00 January, 01 2012 09:00:00 3600 01:00:00
2 January, 01 2012 08:30:00 January, 01 2012 10:30:00 7200 02:00:00
3 January, 01 2012 09:00:00 January, 02 2012 12:00:00 97200 03:00:00
Обратите внимание на вводящий в заблуждение "03:00:00" для 27-часовой разницы по номеру 3.
Ответ 2
ОБНОВЛЕНО:
Правильно вычислить временной интервал в SQL Server, , даже если более 24 часов:
-- Setup test data
declare @minDate datetime = '2012-12-12 20:16:47.160'
declare @maxDate datetime = '2012-12-13 15:10:12.050'
-- Get timespan in hh:mi:ss
select cast(
(cast(cast(@maxDate as float) - cast(@minDate as float) as int) * 24) /* hours over 24 */
+ datepart(hh, @maxDate - @minDate) /* hours */
as varchar(10))
+ ':' + right('0' + cast(datepart(mi, @maxDate - @minDate) as varchar(2)), 2) /* minutes */
+ ':' + right('0' + cast(datepart(ss, @maxDate - @minDate) as varchar(2)), 2) /* seconds */
-- Returns 18:53:24
Особенно приветствуются крайние случаи, которые показывают неточность.
Ответ 3
DECLARE @EndTime AS DATETIME, @StartTime AS DATETIME
SELECT @StartTime = '2013-03-08 08:00:00', @EndTime = '2013-03-08 08:30:00'
SELECT CAST(@EndTime - @StartTime AS TIME)
Результат: 00:30:00.0000000
Форматируйте результат по своему усмотрению.
Ответ 4
Посмотрите, поможет ли это. Я могу установить переменные для прошедших дней, часов, минут, секунд. Вы можете отформатировать это по своему вкусу или включить в определенную пользователем функцию.
Примечание. Не используйте DateDiff (hh, @Date1, @Date2). Это ненадежно! Он обходит непредсказуемыми способами
Учитывая две даты... (Примеры дат: два дня, три часа, 10 минут, разница 30 секунд)
declare @Date1 datetime = '2013-03-08 08:00:00'
declare @Date2 datetime = '2013-03-10 11:10:30'
declare @Days decimal
declare @Hours decimal
declare @Minutes decimal
declare @Seconds decimal
select @Days = DATEDIFF(ss,@Date1,@Date2)/60/60/24 --Days
declare @RemainderDate as datetime = @Date2 - @Days
select @Hours = datediff(ss, @Date1, @RemainderDate)/60/60 --Hours
set @RemainderDate = @RemainderDate - (@Hours/24.0)
select @Minutes = datediff(ss, @Date1, @RemainderDate)/60 --Minutes
set @RemainderDate = @RemainderDate - (@Minutes/24.0/60)
select @Seconds = DATEDIFF(SS, @Date1, @RemainderDate)
select @Days as ElapsedDays, @Hours as ElapsedHours, @Minutes as ElapsedMinutes, @Seconds as ElapsedSeconds
Ответ 5
Лучший и простой способ:
Convert(varchar, {EndTime} - {StartTime}, 108)
Как заметил Анри.
Ответ 6
Используйте DATEDIFF для возврата значения в миллисекундах, секундах, минутах, часах,...
DATEDIFF (интервал, дата1, дата2)
интервал ТРЕБУЕТСЯ - Возвращаемая часть времени/даты. Может быть одним из следующих значений:
year, yyyy, yy = Year
quarter, qq, q = Quarter
month, mm, m = month
dayofyear = Day of the year
day, dy, y = Day
week, ww, wk = Week
weekday, dw, w = Weekday
hour, hh = hour
minute, mi, n = Minute
second, ss, s = Second
millisecond, ms = Millisecond
date1, date2 ТРЕБУЕТСЯ - две даты для расчета разницы между
Ответ 7
select convert(varchar, Max(Time) - Min(Time) , 108) from logTable where id=...
Ответ 8
Надеемся, что это поможет вам получить точное время между двумя отметками времени
Create PROC TimeDurationbetween2times(@iTime as time,@oTime as time)
As
Begin
DECLARE @Dh int, @Dm int, @Ds int ,@Im int, @Om int, @Is int,@Os int
SET @Im=DATEPART(MI,@iTime)
SET @Om=DATEPART(MI,@oTime)
SET @Is=DATEPART(SS,@iTime)
SET @Os=DATEPART(SS,@oTime)
SET @Dh=DATEDIFF(hh,@iTime,@oTime)
SET @Dm = DATEDIFF(mi,@iTime,@oTime)
SET @Ds = DATEDIFF(ss,@iTime,@oTime)
DECLARE @HH as int, @MI as int, @SS as int
if(@Im>@Om)
begin
SET @[email protected]
end
if(@Is>@Os)
begin
SET @[email protected]
end
SET @HH = @Dh
SET @MI = @Dm-(60*@HH)
SET @SS = @Ds-(60*@Dm)
DECLARE @hrsWkd as varchar(8)
SET @hrsWkd = cast(@HH as char(2))+':'+cast(@MI as char(2))+':'+cast(@SS as char(2))
select @hrsWkd as TimeDuration
End