DATEDIFF между двумя датами для возврата отметки времени - PullRequest
0 голосов
/ 28 мая 2020

РЕШЕНО

CONCAT((DATEDIFF(Minute,START_DTTM,END_DTTM)/60),'h:',
       (DATEDIFF(Minute,START_DTTM,END_DTTM)%60) 'm') AS TotalTimeMissing 

Выдает TotalTimeMissing: 5h: 13m

________

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

РЕДАКТИРОВАТЬ: Код был обновлен и теперь включает код от Сами. Я также добавил дополнительный код, который я исключил из оригинала.

Вот текущий код:

USE PACKAGE

GO  

SELECT

        dp.LEGACY_ID

       ,dp.SURNAME

       ,dp.FORENAME

       ,dp.ETHNICITY_DESCRIPTION

       ,dp.BIRTH_DTTM

       ,DATEDIFF(YY, dp.BIRTH_DTTM, GETDATE()) -

            CASE

                  WHEN RIGHT(CONVERT(VARCHAR(6), GETDATE(), 12), 4) >=

                        RIGHT(CONVERT(VARCHAR(6), dp.BIRTH_DTTM, 12), 4)

                        THEN 0

                  ELSE 1

            END AS [Current Age]

--^Precise age calc due to potential LL inaccuracy

       ,mp.DIM_PERSON_ID

       ,mp.MISSING_STATUS

       ,mp.START_DTTM

       ,mp.END_DTTM

       ,dp.LEGACY_ID

       ,mp.RETURN_INT_OFFERED

       ,mp.RETURN_INT_ACCEPTED

       ,mp.RETURN_INT_DATE


FROM C_S.FACT_MISSING_PACKAGE AS mp

JOIN C_S.FACT_MISSING_PACKAGE AS dp ON mp.DIM_PERSON_ID = dp.DIM_PERSON_ID

WHERE CAST (mp.START_DTTM AS DATE)

              BETWEEN DATEADD(YY, -1, CAST (GETDATE() AS DATE)) AND CAST (GETDATE() AS DATE)

--^Displays all records within exactly 1 year of run date

       UNION (SELECT CONCAT(Value / 3600 / 24,

              ' Days ',

              RIGHT(CONCAT('00', Value / 3600 % 24), 2),

              ':',

              RIGHT(CONCAT('00', Value / 60 % 60), 2),

              ':',

              RIGHT(CONCAT('00',Value % 3600 % 60), 2)

       ) AS TotalTimeMissing

FROM

(

  SELECT mp.DIM_PERSON_ID, DATEDIFF(Second, mp.START_DTTM, mp.END_DTTM) Value

  FROM C_S.FACT_MISSING_PACKAGE AS mp

) T(Value))


ORDER BY START_DTTM ASC;

Сами получил меня почти все, но когда я запустил Приведенный выше код я получаю сообщение об ошибке в отношении UNION и T, при этом T не указывает необходимое количество столбцов. Чтобы решить эту проблему, я попытался поместить начальный раунд столбцов SELECT в оператор (SELECT CONCAT (), но он генерирует ошибки, поэтому я немного не понимаю, как это исправить?

Мне нужно вернуть все эти столбцы с дополнительным столбцом в конце как TotalTimeMissing

Спасибо

Ответы [ 3 ]

1 голос
/ 28 мая 2020

Вы можете сначала рассчитать разницу в минутах, используя функцию DATEDIFF, а затем вычислить часы и дни, зная, что 1 час составляет 60 минут, а 1 день - 1440 минут.

Помните, как DATEDIFF работает на SQL сервере:

Эта функция возвращает количество (в виде целого числа со знаком) указанной части даты границ , пересеченных между указанными startdate и enddate.

Итак,

DATEDIFF(day, '2020-01-13 23:59:58', '2020-01-14 00:00:08')

вернет 1, даже если разница составляет всего несколько секунд, потому что данный интервал пересекает границу дня (полночь) .

Вот почему вы не должны использовать здесь DATEDIFF(day, ...), а используйте DATEDIFF(minute, ...) или DATEDIFF(second, ...) и рассчитайте количество часов и дней на основе общего количества прошедших минут или секунд.

Я буду использовать CROSS APPLY, чтобы не печатать длинное выражение много раз. Я также использую здесь целочисленное деление /, которое отбрасывает дробную часть, например 200 / 60 = 3.

Total days = total minutes / 1440 (discard fractional part)
Total hours = total minutes / 60 (discard fractional part)

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

Hours = Total hours % 24

Для последних минут нам нужен только остаток минут после общего количества дней и часов, следовательно,

Minutes = total minutes mod 60.

Запрос:

SELECT 
     dp.LEGACY_ID
    ,dp.SURNAME
    ,dp.FORENAME
    ,mp.DIM_PERSON_ID
    ,mp.MISSING_STATUS
    ,mp.START_DTTM
    ,mp.END_DTTM
    ,dp.LEGACY_ID
    ,STR(DiffMinutes / 1440) + ':' +        -- total days
     STR(DiffMinutes / 60 % 24) + ':' +     -- hours (0 .. 23)
     STR(DiffMinutes % 60) AS TimeMissing   -- minutes (0 .. 59)
FROM 
    MissingPackages AS mp
    JOIN DIM_PERSON AS dp ON mp.DIM_PERSON_ID = dp.DIM_PERSON_ID
    CROSS APPLY
    (
        SELECT DATEDIFF(minute, mp.START_DTTM, mp.END_DTTM) AS DiffMinutes
    ) AS A
ORDER BY START_DTTM ASC;
0 голосов
/ 28 мая 2020

Это то, что вы ищете

CREATE TABLE MyData 
(
  StartDate DATETIME, 
  EndDate DATETIME
);

INSERT INTO MyData VALUES
('2017-01-01 00:00:00', '2018-01-02 00:25:01'),
('2017-01-01 00:00:00', '2018-01-01 00:00:00'),
('2017-01-02 12:00:09', '2017-01-02 12:00:30'),
('2017-01-01 02:00:00', '2017-01-01 03:30:30'),
('2017-01-01 00:00:00', '2017-01-03 00:30:30'),
('2017-12-31 23:59:59', '2018-01-01 00:00:01'),
('2017-12-31 23:59:01', '2018-01-01 00:00:01');


SELECT CONCAT(Value / 3600 / 24, 
              ' Days ', 
              RIGHT(CONCAT('00', Value / 3600 % 24), 2), 
              ':', 
              RIGHT(CONCAT('00', Value / 60 % 60), 2), 
              ':',
              RIGHT(CONCAT('00',Value % 3600 % 60), 2)
       ) TimeMissing 
FROM
(
  SELECT DATEDIFF(Second, StartDate, EndDate) Value
  FROM MyData
) T(Value);

Возвращает:

+-------------------+
|    TimeMissing    |
+-------------------+
| 366 Days 00:25:01 |
| 365 Days 00:00:00 |
| 0 Days 00:00:21   |
| 0 Days 01:30:30   |
| 2 Days 00:30:30   |
| 0 Days 00:00:02   |
| 0 Days 00:01:00   |
+-------------------+
0 голосов
/ 28 мая 2020
CONCAT(DATEDIFF(day, START_DT, END_DT), '-', DATEDIFF(hour, START_DT, END_DT), '-', DATEDIFF(minute, START_DT, END_DT)) AS TimeMissing
...