【问题标题】:DATEDIFF between two dates to return timestamp两个日期之间的 DATEDIFF 返回时间戳
【发布时间】:2020-09-15 19:08:33
【问题描述】:

已解决

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

产生 TotalTimeMissing:5h:13m

________

我正在尝试返回两个特定日期之间的时间戳值,以计算出包裹丢失和被发现之间的时间。

编辑:代码已更新为包含来自 Sami 的代码。我还添加了从原始代码中排除的附加代码。

这是当前代码:

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;

Sami 帮我解决了大部分问题,但是当我运行上面的代码时,我得到一个与 UNION 和 T 相关的错误,T 没有说明所需的列数。为了解决这个问题,我尝试将第一轮 SELECT 列放入 (SELECT CONCAT() 语句中,但它会产生错误,所以当谈到如何修复它时我有点茫然?

我需要返回所有这些列,并在末尾添加一列作为 TotalTimeMissing

谢谢

【问题讨论】:

  • 请提供样本数据和期望的结果。
  • 更新原帖!

标签: sql sql-server tsql datediff


【解决方案1】:

您可以先使用DATEDIFF 函数计算以分钟为单位的差异,然后在知道 1 小时为 60 分钟而 1 天为 1440 分钟的情况下计算小时和天数。

注意DATEDIFF 在 SQL Server 中工作:

此函数返回计数(作为有符号整数值) 指定的日期部分 边界 在指定的开始日期之间交叉 和结束日期。

所以,

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)

但是,我们不需要 total 小时,我们需要在总天数之后剩余的小时数,因此我们需要取 mod 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;

【讨论】:

    【解决方案2】:

    这是要找的吗

    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   |
    +-------------------+
    

    【讨论】:

    • 当你看到你的代码为这两个datetimes:2017-12-31 23:59:59, 2018-01-01 00:00:01返回什么时,我想你会感到惊讶
    • 我已将原始帖子更新为更具体,这不是我想要的,但它是正确的!
    • 谢谢你,我已经再次更新了原来的帖子,因为这几乎是我需要的,但我不断收到错误
    【解决方案3】:
    CONCAT(DATEDIFF(day, START_DT, END_DT), '-', DATEDIFF(hour, START_DT, END_DT), '-', DATEDIFF(minute, START_DT, END_DT)) AS TimeMissing
    

    【讨论】:

    • 不完全,我不是在找:1-24-1440 我在找:start_dttm: 2020-01-01 10:00:00 end_dttm: 2020-01-02 10: 00:00 返回:24:00:00 作为 TimeDiff
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-19
    相关资源
    最近更新 更多