我正在尝试计算进出时间之间的时差。
使用以下代码时,它给出的数据错误。
(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
答案 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