计算两个具有HH.MM格式时间的varchar2列之间的时差

时间:2019-03-27 05:52:54

标签: sql oracle time

我正在尝试计算进出时间之间的时差。

使用以下代码时,它给出的数据错误。

(SELECT round(24 * (to_date(SIGN_OUT_TIME,'hh24:mi') - 
to_date(SIGN_IN_TIME,'hh24:mi')),2) diff_hours
FROM XXBCT.XXBCT_BIO_OTL_ENTRIES_SUMMARY
WHERE EMPLOYEE_NUMBER='112319'
AND attendance_dt    ='04-Jan-19');

结果应该是08.13,但给出的是8.22

3 个答案:

答案 0 :(得分:0)

8,22是小时差。分钟不是0.22。那是整个小时的一部分。这对应于预期的13分钟。

这是您可以做得更好的一种方法。 您可以在几秒钟内获得差异化 然后您可以根据需要获取小时,分钟和秒数

select TO_CHAR(TRUNC(diff_seconds/3600),'FM9900') || '.' ||
       TO_CHAR(TRUNC(MOD(diff_seconds,3600)/60),'FM00') || '.' ||
       TO_CHAR(MOD(diff_seconds,60),'FM00')
  from (SELECT round(24 * 60 * 60 (to_date(SIGN_OUT_TIME,'hh24:mi') 
                                 - to_date(SIGN_IN_TIME,'hh24:mi')),2) diff_seconds
          FROM XXBCT.XXBCT_BIO_OTL_ENTRIES_SUMMARY
          WHERE EMPLOYEE_NUMBER='112319'
          AND attendance_dt    ='04-Jan-19'
        );

答案 1 :(得分:0)

由于时差,Oracle具有一种数据类型,称为interval

http://www.oracletutorial.com/oracle-basics/oracle-interval/

  

Oracle为您提供了两种日期时间数据类型:DATE和TIMESTAMP,用于存储时间点数据。此外,它提供了INTERVAL数据类型,该数据类型使您可以存储时间段。

对于我来说,这是我更喜欢使用时差的方式,因为它可以节省所有繁琐的计算,而仅在处理日期时则需要这样做。以下查询中的“技巧”是我通过to_timestamp将一个日期转换为时间戳。 timestamp减去date会给您interval作为回报:

with 
first_date_vc2   as (select                '01:00' val from dual),
second_date_vc2  as (select                '09:13' val from dual),
first_date_date  as (select to_date(val,'HH24:MI') val from first_date_vc2),
second_date_date as (select to_date(val,'HH24:MI') val from second_date_vc2)
select 
    to_timestamp(sdd.val)-fdd.val 
from first_date_date fdd,second_date_date sdd;

-- TO_TIMESTAMP(SDD.VAL)-FDD.VAL
-- +00 08:13:00.000000

包括所需的输出格式:

with 
first_date_vc2   as (select                '01:00'        val from dual),
second_date_vc2  as (select                '09:13'        val from dual),
first_date_date  as (select to_date(val,'HH24:MI')        val from first_date_vc2),
second_date_date as (select to_date(val,'HH24:MI')        val from second_date_vc2),
interval_between as (select to_timestamp(sdd.val)-fdd.val val from first_date_date fdd,second_date_date sdd)
select 
    extract( hour from val)||':'||extract( minute from val) val
from interval_between;

-- VAL
-- 8:13

正如评论员已经指出的那样,所需的实际查询会因要求而异,例如它可能会超过24小时还是会持续午夜。

答案 2 :(得分:0)

8小时13分钟= 8.22小时

如果您只希望数字以小时为单位,小数以分钟为单位,则可以将答案的小数部分乘以0.6

Oracle设置

CREATE TABLE XXBCT_BIO_OTL_ENTRIES_SUMMARY (
  EMPLOYEE_NUMBER, ATTENDANCE_DT, SIGN_IN_TIME, SIGN_OUT_TIME
)
AS
SELECT '112319',
       DATE '2019-01-04',
       TO_CHAR( TIMESTAMP '2019-01-04 00:00:00', 'HH24:MI' ),
       TO_CHAR( TIMESTAMP '2019-01-04 08:13:00', 'HH24:MI' )
FROM   DUAL

查询

SELECT ROUND( diff_hours, 2 ) AS diff_hours,
       TRUNC( diff_hours ) + MOD( diff_hours, 1 ) * 0.60 AS diff_hours_hhmi
FROM   (
  SELECT 24 * (to_date(SIGN_OUT_TIME,'hh24:mi') - to_date(SIGN_IN_TIME,'hh24:mi'))
           AS diff_hours
  FROM   XXBCT_BIO_OTL_ENTRIES_SUMMARY
  WHERE  EMPLOYEE_NUMBER = '112319'
  AND    attendance_dt   = DATE '2019-01-04'
);

输出

DIFF_HOURS | DIFF_HOURS_HHMI
---------: | --------------:
      8.22 |            8.13

您还可以使用INTERVAL数据类型:

SELECT TO_TIMESTAMP(SIGN_OUT_TIME,'hh24:mi') - TO_TIMESTAMP(SIGN_IN_TIME,'hh24:mi') AS diff_hours_interval,
       SUBSTR(TO_TIMESTAMP(SIGN_OUT_TIME,'hh24:mi') - TO_TIMESTAMP(SIGN_IN_TIME,'hh24:mi'), 12, 5 ) AS diff_hours_interval_string
FROM   XXBCT_BIO_OTL_ENTRIES_SUMMARY
WHERE  EMPLOYEE_NUMBER = '112319'
AND    attendance_dt   = DATE '2019-01-04';
DIFF_HOURS_INTERVAL           | DIFF_HOURS_INTERVAL_STRING
:---------------------------- | :-------------------------
+000000000 08:13:00.000000000 | 08:13                     

db <>提琴here