Как я могу найти разницу во времени в двух датах? - PullRequest
0 голосов
/ 20 июня 2019

Я пытаюсь использовать функцию DATEDIFF(), чтобы найти разницу между двумя датами в таблице.У меня проблема в том, чтобы понять, как вычесть время из самой последней даты в таблице VS из начальной даты.

Даты в формате: YYYY-MM-DD HH:MM:SS

Я пробовал это:

select FileName, '20:00' as StartTime, ModifiedDate, DATEDIFF(MINUTE, 
'20:00', ModifiedDate) as 'BackupTime' 
from BackLogData

Но он возвращает минуты от времени начала.

Вот пример таблицы:

+-----------+-----------------------------+------------+
| StartTime |        ModifiedDate         | BackupTime |
+-----------+-----------------------------+------------+
| 20:00     | 2019-06-10 01:04:17.3692999 |   62817424 |
| 20:00     | 2019-06-10 00:53:23.4900986 |   62817413 |
| 20:00     | 2019-06-10 00:51:09.2363761 |   62817411 |
+-----------+-----------------------------+------------+

Правильная таблица:

+-----------+-----------------------------+------------+--+
| StartTime |        ModifiedDate         | BackupTime |  |
+-----------+-----------------------------+------------+--+
| 20:00     | 2019-06-10 01:04:17.3692999 |         11 |  |
| 20:00     | 2019-06-10 00:53:23.4900986 |          2 |  |
| 20:00     | 2019-06-10 00:51:09.2363761 |        291 |  |
+-----------+-----------------------------+------------+--+

Ответы [ 4 ]

1 голос
/ 21 июня 2019

Марк Гильо был на правильном пути, но я обнаружил некоторые проблемы с его запросом.Вот ревизия:

--this is setup, you don't need this
CREATE TABLE t
    ([StartTime] time, [ModifiedDate] datetime)
;

INSERT INTO t
    ([StartTime], [ModifiedDate])
VALUES
    ('20:00', '2019-06-10 01:04:17'),
    ('20:00', '2019-06-10 00:53:23'),
    ('20:00', '2019-06-10 00:51:09')
;

--we now have a table with a TIME column (cast it in the cte if yours is not), a DATETIME
with LOGS as (
  select StartTime,
         ModifiedDate,
         DATEADD(DAY, -1, CAST(CAST(ModifiedDate as DATE) as DATETIME)) as ModifiedMidnightDayBefore,
         CAST(StartTime as DateTime) as StartDateTime,
         row_number() over (order by ModifiedDate) as num
  from t
)
select curr.StartTime, 
       curr.ModifiedDate, 
       datediff(minute, 
            COALESCE(
               prev.ModifiedDate, 
               curr.ModifiedMidnightDayBefore + curr.StartDateTime
            ),
            curr.ModifiedDate) as BackupTime
from 
  LOGS curr
  left join LOGS as prev on prev.num = curr.num - 1
order by curr.num

LOGS CTE присоединяется к себе в num = num-1, тем самым объединяя текущую строку и данные предыдущей строки в строку.В одной строке не будет предыдущих данных (пусто), поэтому, когда мы делаем наш datediff, мы используем coalesce, который похож на ISNULL, но поддерживается всеми основными поставщиками БД.COALESCE возвращает первый ненулевой аргумент.Он используется для заполнения значения, если для измененной даты нет значения PREVious

DATEDIFF предыдущего против текущего довольно очевидно.Хитрость заключается в логике, если нет предыдущего значения:

CTE также преобразует дату и время модифицированной даты в дату, чтобы отбросить компонент времени (установить его в полночь) и вернуться к дате (так чтопоявляется из dateadd как datetime).Dateadd вычитает один день из этого, поэтому в предыдущий день наступает полночь, а затем мы добавляем к этому наше время начала (8 вечера).Таким образом, минимальная дата в таблице преобразуется в полночь, возвращается на день назад, а затем добавляется 8 вечера, поэтому она становится «8 вечера в день, предшествующий измененной дате», и тогда мы можем точно установить это значение до 291 минуты

1 голос
/ 20 июня 2019

Если все, что вам нужно, это разница минут от часа '20: 00' по сравнению со временем ModifiedDate, вам нужно просто сравнить значения времени:

Попробуйте:

SELECT [FileName]
     , '20:00' AS [StartTime]
     , [ModifiedDate]
     , DATEDIFF(MINUTE, '20:00', CONVERT(TIME, [ModifiedDate])) AS 'BackupTime' --convert your modified date to time 
FROM   [BackLogData];

Причина, по которой вы получили странное большое значение, заключается в том, что вы пытались найти разницу между 19:00 - 01:00 и 20:00 и вашей ModifiedDate.

1 голос
/ 20 июня 2019

Вы можете измерить разницу в минутах и ​​преобразовать ее в тип данных времени, используя dateadd и cast. Обратите внимание, что если ваша разница больше 24 часов, это не сработает (тип данных времени хранит до 24 часов).

SELECT FileName, '20:00' AS StartTime, ModifiedDate,
cast(dateadd(minute,DATEDIFF(MINUTE, RecordDate, ModifiedDate),'19000101') as time(0)) AS 'BackupTime' 
FROM BackLogData

Пример:

SELECT 
cast(dateadd(minute,DATEDIFF(MINUTE, '2019-05-05 16:00:00', '2019-05-05 18:00:00'),'19000101') as time(0)) AS 'BackupTime' 

Выход:

02:00:00
0 голосов
/ 20 июня 2019

Чтобы получить предыдущий раз, вы можете объединить свой стол с самим собой.Но сначала я бы нумеровал строки в CTE, так что теперь вы можете установить простое условие для объединения каждой строки с предыдущей строкой.

Этот запрос возвращает разницу между каждым ModifiedTime и его предыдущим (или StartDate дляпервая строка), в результате чего вы получили желаемый набор результатов:

declare @StartTime time = convert(time, '20:00');

declare @StartDate datetime = (select convert(datetime, dateadd(day, -1, convert(date, max(ModifiedDate)))) + 
                                      convert(datetime, @StartTime)
                               from BackLogData);

with LOGS as (
  select ModifiedDate,
         row_number() over (order by ModifiedDate) as num
  from BackLogData
)
select @StartTime as StartTime, 
       LOGS.ModifiedDate, 
       datediff(minute, 
                case when LOGS.num = 1 then @StartDate else PREVIOUS.ModifiedDate end,
                LOGS.ModifiedDate) as BackupTime
from LOGS
     left join LOGS as PREVIOUS on PREVIOUS.num = LOGS.num - 1
order by LOGS.num

PS: как отметил Кайус Джард, чтобы иметь возможность напрямую рассчитать разницу во времени между ModifiedDate и StartTime, мы должны преобразоватьStartTime до даты и времени, используя часть даты последнего изменения ModifiedDate минус один (то есть, он начался днем ​​ранее).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...