时间上的差异给出了不正确的结果

时间:2016-07-25 02:18:55

标签: sql sql-server-2008

我有一张表作为测试

with
     job_events ( userid, eventstartdt, jobcode ) as (
       select 10, date '2014-08-18', 'j1' from dual union all
       select 10, date '2015-07-27', 'j1' from dual union all
       select 10, date '2015-03-23', 'j2' from dual union all
       select 10, date '2015-12-28', 'j3' from dual union all
       select 10, date '2015-03-23', 'j4' from dual union all
       select 10, date '2015-03-23', 'j5' from dual union all
       select 35, date '2014-04-18', 'j1' from dual union all
       select 35, date '2015-09-22', 'j1' from dual union all
       select 35, date '2015-10-29', 'j8' from dual
     ),
     comp_events ( userid, eventstartdt, salary ) as (
       select 10, date '2014-08-11', 1000 from dual union all
       select 10, date '2015-03-23', 1525 from dual union all
       select 10, date '2015-06-21',  500 from dual union all
       select 10, date '2016-03-21', 2000 from dual union all
       select 35, date '2015-06-15', 2850 from dual
     ),
     u ( userid, eventstartdt, jobcode, salary ) as (
       select userid, eventstartdt, jobcode, null    from   job_events
       union all
       select userid, eventstartdt, null   , salary  from   comp_events
     ),
     prep ( userid, eventstartdt, jobcode, salary ) as (
       select userid, eventstartdt, jobcode, 
              last_value(salary ignore nulls) over 
                          (partition by userid order by eventstartdt)
       from   u
     )
select   userid, eventstartdt, jobcode, salary
from     prep
where    jobcode is not null
order by userid, jobcode, eventstartdt
;

Shiftend的数据类型为time out的数据类型为smalldatetime

我期待输出为

    USERID EVENTSTARTDT JOBCODE     SALARY
---------- ------------ ------- ----------
        10 2014-08-18   j1            1000
        10 2015-07-27   j1             500
        10 2015-03-23   j2            1525
        10 2015-12-28   j3             500
        10 2015-03-23   j4            1525
        10 2015-03-23   j5            1525
        35 2014-04-18   j1
        35 2015-09-22   j1            2850
        35 2015-10-29   j8            2850

9 rows selected.

我正在尝试此查询:

shiftend            |        out            |       
---------------------------------------------   
15:00:00.0000000    |   2016-07-22 14:42:00 |   
16:00:00.0000000    |   2016-07-22 16:06:00 |       

但我得到的输出为

shiftend            |         out           |   Output    
-----------------------------------------------------------------------------   
15:00:00.0000000    |   2016-07-22 14:42:00 |   -00:18:00   
16:00:00.0000000    |   2016-07-22 16:06:00 |    00:06:00   

23:42:00不正确。如何计算时间。

1 个答案:

答案 0 :(得分:1)

尝试以下查询:

select 
 case when (cast(out as time) < shiftend) then '-' else '' end + 
 convert(varchar(8), 
  dateadd(minute, 
   abs(
    DATEDIFF(minute, 
     cast(out as time)
    , shiftend)
   )
 ,0)
,108) as Output

说明:

  • 您可以通过DATEDIFF(minute, cast(out as time), shiftend)获得两个日期之间的差异。

  • 您只需要time组件即可避免前一天,因此您使用cast(out as time)。您提到的shiftend已经是数据类型time

  • abs返回绝对值,因此-18变为18。

  • 然后使用00:00:00

  • 将上述值作为分钟添加到dateadd(minute, [above value], 0)来生成日期
  • 最后convert(varchar(8),____,108)是因为您需要输出作为时间。

  • iif(cast(out as time) < shiftend,'-','')会在字词的开头添加否定号。

不幸的是,time数据类型中不能包含负值。它正在转变为-18至00:00,即23:42。你可以:

  • 使用datediff并将差异保存为秒数,例如。
  • 仅保存模块化差异,并有一个单独的列来确定它是正面还是负面的差异。
  • 编写您自己的SQL函数,将其计算为varchar,如上所述