【问题标题】:Calculating duration between two dates which go over months (splitting)计算超过几个月的两个日期之间的持续时间(拆分)
【发布时间】:2019-05-14 16:08:23
【问题描述】:

我正在考虑计算 SQL (SQL Server) 中两个日期字段之间的差异,这两个日期字段可能(也可能不会)与另一个月份重叠。

我有一个 TimeFrom 字段、一个 TimeTo 字段和一个状态字段。两个时间字段都是日期时间格式,状态是数字。

以下是日期示例:

TimeFrom               TimeTo                Status
2018-04-01 09:03:27    2018-07-15 10:11:13   12

我需要计算这些日期之间的时间,但在相关月份,我自己正在努力解决这个问题。

输出看起来像:

YearMonth | Status | Duration (hh:mm:ss)
2018-04 | 12      | xx:xx:xx
2018-05 | 12 | xx:xx:xx
2018-06 | 12 | xx:xx:xx

【问题讨论】:

  • 能否提供您使用的数据库系统。
  • 我们想要样本表数据和匹配的预期结果! (仍然是格式化的文本,而不是图像。)
  • 七月的时间流逝呢??
  • 您使用的是哪个DBMS 产品? “SQL”只是一种查询语言,而不是特定数据库产品的名称。请为您正在使用的数据库产品添加tag postgresql, oracle, sql-server, db2, ...
  • 你猜的时间应该是天小时分秒!!

标签: sql sql-server time split difference


【解决方案1】:

建议的解决方案...

SET DATEFORMAT YMD
DECLARE @aux TABLE (TimeFrom datetime, TimeTo datetime, Status int)
DECLARE @res TABLE (YearMonth varchar(7), Status int, Sc int)

INSERT INTO @aux VALUES ('2018-04-01 09:03:27','2018-07-15 10:11:13',12)

DECLARE @secs int, @dt datetime, @fi datetime, @fo datetime,
        @f1 datetime, @f2 datetime, @st int

SELECT TOP 1 @fi = TimeFrom, @fo = TimeTo, @st = status FROM @aux

SELECT @dt = DATEADD(mm, DATEDIFF(mm, 0, @fi), 0), @f1 = @fi
WHILE @dt < @fo
BEGIN
    SELECT @f2 = CASE 
            WHEN DATEADD(mm, 1, @dt) < @fo
                THEN DATEADD(mm, 1, @dt)
                ELSE DATEADD(ss, 1, @fo)
            END
    SELECT @secs = DATEDIFF(ss, @f1, DATEADD(s, - 1, @f2))
    INSERT INTO @res VALUES (CONVERT(varchar(7), @dt, 120), @st, @secs)
    SELECT @f1 = @f2, @dt = DATEADD(mm, 1, @dt)
END

SELECT YearMonth,status
    ,CAST(Sc / 3600 AS varchar) + '.'
    +RIGHT('0' + CAST((Sc - 3600 * (Sc / 3600)) / 60 AS varchar(2)), 2) + '.'
    +RIGHT('0' + CAST(Sc % 60 AS varchar(2)), 2) AS [Duration (hhh.mm.ss)]
FROM @res

【讨论】:

    【解决方案2】:

    这应该可行:

    set serveroutput on;
    create or replace procedure d061(d1  in  date, d2  in date ) as
    dd number;
    hh24 number;
    mi number;
    ss number;
    begin
    select extract(day from intrvl) into  dd
        from (
              select   to_timestamp_tz (d1,'DD MON YYYY hh24:mi:ss')
                     - to_timestamp_tz (d2,'DD MON YYYY hh24:mi:ss') as intrvl
             from dual
             );
    
    
    select  extract(hour from intrvl) into hh24
            from (
              select   to_timestamp_tz (d1,'DD MON YYYY hh24:mi:ss')
                     - to_timestamp_tz (d2,'DD MON YYYY hh24:mi:ss') as intrvl
             from dual
             );
    select  extract(minute from intrvl) into mi
    
            from (
              select   to_timestamp_tz (d1,'DD MON YYYY hh24:mi:ss')
                     - to_timestamp_tz (d2,'DD MON YYYY hh24:mi:ss') as intrvl
             from dual
             );
    
    
    select extract(second from intrvl) into ss from (
              select   to_timestamp_tz (d1,'DD MON YYYY hh24:mi:ss')
                     - to_timestamp_tz (d2,'DD MON YYYY hh24:mi:ss') as intrvl
             from dual
             );
            DBMS_OUTPUT.PUT_LINE('DD  HH24  MI SS');
            DBMS_OUTPUT.PUT_LINE(dd || '  '||hh24||'  ' ||mi||'  ' ||ss);
    end;
    /
    
    declare
    begin 
    d061(sysdate+1,sysdate);
    end;
    /
    

    输出:

    DD  HH24  MI SS
    1  0  0  0
    

    【讨论】:

    • 对未指定 dbms 的问题的产品特定答案。至少告诉我们这是用于哪个 dbms。
    • 抱歉,我忘记补充说我使用的是 SQL Server。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 2014-02-28
    • 2021-04-28
    • 2020-12-25
    • 1970-01-01
    相关资源
    最近更新 更多