以小时和分钟计算两个日期之间的差异
Find the difference between two dates in hours and minutes
我正在尝试想出一种方法来计算两个日期之间的时差和分钟差。
我有一个包含两列 Start Date
和 TimeStamp
的 table:
Start Date Timestamp
-------------------- --------------------
05/JAN/2016 05:30:00 01/JAN/2016 10:02:29
30/JAN/2016 06:10:00 18/JAN/2016 19:24:00
23/JAN/2016 06:10:00 08/JAN/2016 10:46:00
05/JAN/2016 05:30:00 30/DEC/2015 16:07:00
23/JAN/2016 06:10:00 08/JAN/2016 12:18:05
01/JAN/2016 14:10:00 16/DEC/2015 16:36:56
01/JAN/2016 14:10:00 16/DEC/2015 11:41:00
03/JAN/2016 05:15:00 02/JAN/2016 11:23:15
03/JAN/2016 05:15:00 02/JAN/2016 07:52:00
我使用查询:
select ROUND(RM_LIVE.CRWGNDACTTIME.GNDACTSTARTRM_LIVE.TRANSACTIONLOG.TIMESTAMP,2)
AS "Difference"
from Transaction;
查询结果为:
0.002721428571428571428571428571428571428571
0.008178571428571428571428571428571428571429
0.0105785714285714285714285714285714285714
0.003971428571428571428571428571428571428571
预期结果:
133:23
91:28
355:24
353:52
274:46
我使用这个公式在 Excel 中得到了预期的结果:
= MAX(T982+U982,W982+V982) - MIN(T982+U982,W982+V982)
如何在 Oracle SQL 中获得相同的结果?
CASE
WHEN trunc(24 * abs(RM_LIVE.TRANSACTIONLOG.TIMESTAMP
- RM_LIVE.CRWGNDACTTIME.GNDACTSTART))
||':'|| lpad(round(60 * mod(24 * abs(RM_LIVE.TRANSACTIONLOG.TIMESTAMP
- RM_LIVE.CRWGNDACTTIME.GNDACTSTART), 1)), 2, '0') <= '11:00' THEN 'LESS'
ELSE 'MORE'
END AS "mORE/LESS",
386:29 1055 01-JAN-16 16-DEC-15 MORE
**102:41 1055 08-NOV-15 04-NOV-15 LESS**
381:33 1055 01-JAN-16 16-DEC-15 MORE
176:45 1055 20-NOV-15 12-NOV-15 MORE
**119:54 1055 08-NOV-15 03-NOV-15 LESS**
我在 中展示了一些变体和解释,但它似乎比你想要的要多一些——你不想看到秒数——并且不允许更多超过 100 小时。
获得所需输出的最简单方法是:
trunc(24 * (RM_LIVE.CRWGNDACTTIME.GNDACTSTART
- RM_LIVE.TRANSACTIONLOG.TIMESTAMP))
||':'|| lpad(round(60 * mod(24 * (RM_LIVE.CRWGNDACTTIME.GNDACTSTART
- RM_LIVE.TRANSACTIONLOG.TIMESTAMP), 1)), 2, '0')
as difference
第一部分获取完整的小时数,这类似于您在评论中添加的方法,但截断而不是四舍五入以仅获取完整的小时数。然后是冒号分隔符。然后通过从小时计算中获取余数来计算分钟 - 通过 mod()
- 这是小时的小数,并将其乘以 60。 lpad()
将前导零添加到分钟数,但您可以改用 to_char()
。
如果您混合使用时间戳可能在开始时间之前或之后的范围,那么您可以使用 the abs()
function 来始终获得肯定的结果。
trunc(24 * abs(RM_LIVE.CRWGNDACTTIME.GNDACTSTART
- RM_LIVE.TRANSACTIONLOG.TIMESTAMP))
||':'|| lpad(round(60 * mod(24 * abs(RM_LIVE.CRWGNDACTTIME.GNDACTSTART
- RM_LIVE.TRANSACTIONLOG.TIMESTAMP), 1)), 2, '0')
as difference
作为演示,您的数据模拟在一个 table:
create table your_table(id, start_time, timestamp) as
select 1, to_date ('05/JAN/2016 05:30:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('01/JAN/2016 10:02:29', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 2, to_date ('30/JAN/2016 06:10:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('18/JAN/2016 19:24:00', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 3, to_date ('23/JAN/2016 06:10:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('08/JAN/2016 10:46:00', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 4, to_date ('05/JAN/2016 05:30:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('30/DEC/2015 16:07:00', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 5, to_date ('23/JAN/2016 06:10:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('08/JAN/2016 12:18:05', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 6, to_date ('01/JAN/2016 14:10:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('16/DEC/2015 16:36:56', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 7, to_date ('01/JAN/2016 14:10:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('16/DEC/2015 11:41:00', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 8, to_date ('03/JAN/2016 05:15:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('02/JAN/2016 11:23:15', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 9, to_date ('03/JAN/2016 05:15:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('02/JAN/2016 07:52:00', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 10, to_date ('16/JAN/2016 11:15:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('16/JAN/2016 12:44:00', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 11, to_date ('16/JAN/2016 11:15:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('16/JAN/2016 12:50:00', 'DD/MON/YYYY HH24:MI:SS') from dual;
等效查询:
select start_time, timestamp, trunc(24 * abs(start_time - timestamp))
||':'|| lpad(round(60 * mod(24 * abs(start_time - timestamp), 1)), 2, '0')
as difference
from your_table
order by id;
START_TIME TIMESTAMP DIFFERENCE
------------------- ------------------- ----------
2016-01-05 05:30:00 2016-01-01 10:02:29 91:28
2016-01-30 06:10:00 2016-01-18 19:24:00 274:46
2016-01-23 06:10:00 2016-01-08 10:46:00 355:24
2016-01-05 05:30:00 2015-12-30 16:07:00 133:23
2016-01-23 06:10:00 2016-01-08 12:18:05 353:52
2016-01-01 14:10:00 2015-12-16 16:36:56 381:33
2016-01-01 14:10:00 2015-12-16 11:41:00 386:29
2016-01-03 05:15:00 2016-01-02 11:23:15 17:52
2016-01-03 05:15:00 2016-01-02 07:52:00 21:23
2016-01-16 11:15:00 2016-01-16 12:44:00 1:29
2016-01-16 11:15:00 2016-01-16 12:50:00 1:35
您无法轻松地将您想要的字符串值 - 它必须是一个具有类似 91:28
值的字符串 - 与其他任何东西进行比较,因为数字的字符串比较效果不佳。如您所见,将“119:54”与“11:00”进行比较实际上是在比较每个字符串的第三个字符,因为前两个字符相同,因此 9
与 :
。
留成小数比较简单:
CASE
WHEN round(24 * abs(RM_LIVE.TRANSACTIONLOG.TIMESTAMP
- RM_LIVE.CRWGNDACTTIME.GNDACTSTART), 2) <= 11 THEN 'LESS"
ELSE 'MORE'
END AS "mORE/LESS",
对于91:28示例,它将比较小数版本91.46;对于 119:54 将比较 119.9,它大于 11; 102:41会被比作102.68,也比11多。
或者您可以通过将固定值除以 24(一天中的几个小时)而不是乘以时差来稍微简化它:
CASE
WHEN abs(RM_LIVE.TRANSACTIONLOG.TIMESTAMP
- RM_LIVE.CRWGNDACTTIME.GNDACTSTART) <= 11/24 THEN 'LESS"
ELSE 'MORE'
END AS "mORE/LESS",
我正在尝试想出一种方法来计算两个日期之间的时差和分钟差。
我有一个包含两列 Start Date
和 TimeStamp
的 table:
Start Date Timestamp
-------------------- --------------------
05/JAN/2016 05:30:00 01/JAN/2016 10:02:29
30/JAN/2016 06:10:00 18/JAN/2016 19:24:00
23/JAN/2016 06:10:00 08/JAN/2016 10:46:00
05/JAN/2016 05:30:00 30/DEC/2015 16:07:00
23/JAN/2016 06:10:00 08/JAN/2016 12:18:05
01/JAN/2016 14:10:00 16/DEC/2015 16:36:56
01/JAN/2016 14:10:00 16/DEC/2015 11:41:00
03/JAN/2016 05:15:00 02/JAN/2016 11:23:15
03/JAN/2016 05:15:00 02/JAN/2016 07:52:00
我使用查询:
select ROUND(RM_LIVE.CRWGNDACTTIME.GNDACTSTARTRM_LIVE.TRANSACTIONLOG.TIMESTAMP,2)
AS "Difference"
from Transaction;
查询结果为:
0.002721428571428571428571428571428571428571
0.008178571428571428571428571428571428571429
0.0105785714285714285714285714285714285714
0.003971428571428571428571428571428571428571
预期结果:
133:23
91:28
355:24
353:52
274:46
我使用这个公式在 Excel 中得到了预期的结果:
= MAX(T982+U982,W982+V982) - MIN(T982+U982,W982+V982)
如何在 Oracle SQL 中获得相同的结果?
CASE
WHEN trunc(24 * abs(RM_LIVE.TRANSACTIONLOG.TIMESTAMP
- RM_LIVE.CRWGNDACTTIME.GNDACTSTART))
||':'|| lpad(round(60 * mod(24 * abs(RM_LIVE.TRANSACTIONLOG.TIMESTAMP
- RM_LIVE.CRWGNDACTTIME.GNDACTSTART), 1)), 2, '0') <= '11:00' THEN 'LESS'
ELSE 'MORE'
END AS "mORE/LESS",
386:29 1055 01-JAN-16 16-DEC-15 MORE
**102:41 1055 08-NOV-15 04-NOV-15 LESS**
381:33 1055 01-JAN-16 16-DEC-15 MORE
176:45 1055 20-NOV-15 12-NOV-15 MORE
**119:54 1055 08-NOV-15 03-NOV-15 LESS**
我在
获得所需输出的最简单方法是:
trunc(24 * (RM_LIVE.CRWGNDACTTIME.GNDACTSTART
- RM_LIVE.TRANSACTIONLOG.TIMESTAMP))
||':'|| lpad(round(60 * mod(24 * (RM_LIVE.CRWGNDACTTIME.GNDACTSTART
- RM_LIVE.TRANSACTIONLOG.TIMESTAMP), 1)), 2, '0')
as difference
第一部分获取完整的小时数,这类似于您在评论中添加的方法,但截断而不是四舍五入以仅获取完整的小时数。然后是冒号分隔符。然后通过从小时计算中获取余数来计算分钟 - 通过 mod()
- 这是小时的小数,并将其乘以 60。 lpad()
将前导零添加到分钟数,但您可以改用 to_char()
。
如果您混合使用时间戳可能在开始时间之前或之后的范围,那么您可以使用 the abs()
function 来始终获得肯定的结果。
trunc(24 * abs(RM_LIVE.CRWGNDACTTIME.GNDACTSTART
- RM_LIVE.TRANSACTIONLOG.TIMESTAMP))
||':'|| lpad(round(60 * mod(24 * abs(RM_LIVE.CRWGNDACTTIME.GNDACTSTART
- RM_LIVE.TRANSACTIONLOG.TIMESTAMP), 1)), 2, '0')
as difference
作为演示,您的数据模拟在一个 table:
create table your_table(id, start_time, timestamp) as
select 1, to_date ('05/JAN/2016 05:30:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('01/JAN/2016 10:02:29', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 2, to_date ('30/JAN/2016 06:10:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('18/JAN/2016 19:24:00', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 3, to_date ('23/JAN/2016 06:10:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('08/JAN/2016 10:46:00', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 4, to_date ('05/JAN/2016 05:30:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('30/DEC/2015 16:07:00', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 5, to_date ('23/JAN/2016 06:10:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('08/JAN/2016 12:18:05', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 6, to_date ('01/JAN/2016 14:10:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('16/DEC/2015 16:36:56', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 7, to_date ('01/JAN/2016 14:10:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('16/DEC/2015 11:41:00', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 8, to_date ('03/JAN/2016 05:15:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('02/JAN/2016 11:23:15', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 9, to_date ('03/JAN/2016 05:15:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('02/JAN/2016 07:52:00', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 10, to_date ('16/JAN/2016 11:15:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('16/JAN/2016 12:44:00', 'DD/MON/YYYY HH24:MI:SS') from dual
union all select 11, to_date ('16/JAN/2016 11:15:00', 'DD/MON/YYYY HH24:MI:SS'), to_date('16/JAN/2016 12:50:00', 'DD/MON/YYYY HH24:MI:SS') from dual;
等效查询:
select start_time, timestamp, trunc(24 * abs(start_time - timestamp))
||':'|| lpad(round(60 * mod(24 * abs(start_time - timestamp), 1)), 2, '0')
as difference
from your_table
order by id;
START_TIME TIMESTAMP DIFFERENCE
------------------- ------------------- ----------
2016-01-05 05:30:00 2016-01-01 10:02:29 91:28
2016-01-30 06:10:00 2016-01-18 19:24:00 274:46
2016-01-23 06:10:00 2016-01-08 10:46:00 355:24
2016-01-05 05:30:00 2015-12-30 16:07:00 133:23
2016-01-23 06:10:00 2016-01-08 12:18:05 353:52
2016-01-01 14:10:00 2015-12-16 16:36:56 381:33
2016-01-01 14:10:00 2015-12-16 11:41:00 386:29
2016-01-03 05:15:00 2016-01-02 11:23:15 17:52
2016-01-03 05:15:00 2016-01-02 07:52:00 21:23
2016-01-16 11:15:00 2016-01-16 12:44:00 1:29
2016-01-16 11:15:00 2016-01-16 12:50:00 1:35
您无法轻松地将您想要的字符串值 - 它必须是一个具有类似 91:28
值的字符串 - 与其他任何东西进行比较,因为数字的字符串比较效果不佳。如您所见,将“119:54”与“11:00”进行比较实际上是在比较每个字符串的第三个字符,因为前两个字符相同,因此 9
与 :
。
留成小数比较简单:
CASE
WHEN round(24 * abs(RM_LIVE.TRANSACTIONLOG.TIMESTAMP
- RM_LIVE.CRWGNDACTTIME.GNDACTSTART), 2) <= 11 THEN 'LESS"
ELSE 'MORE'
END AS "mORE/LESS",
对于91:28示例,它将比较小数版本91.46;对于 119:54 将比较 119.9,它大于 11; 102:41会被比作102.68,也比11多。
或者您可以通过将固定值除以 24(一天中的几个小时)而不是乘以时差来稍微简化它:
CASE
WHEN abs(RM_LIVE.TRANSACTIONLOG.TIMESTAMP
- RM_LIVE.CRWGNDACTTIME.GNDACTSTART) <= 11/24 THEN 'LESS"
ELSE 'MORE'
END AS "mORE/LESS",