草庐IT

Oracle SQL 两个日期类型毫秒值求差,日期转毫秒,时间差(ms)自定义函数解决毫秒差

HezhezhiyuLe 2023-03-28 原文

前言

实际业务经常遇到求平均响应时间等操作,理论上应该可以直接求日期格式毫秒值,便可以计算时间差,But,Oracle没有对应函数,同时网上的方法求得是日期格式化的double类型数据,相加减时,遵循的是十进制,日期格式为60进制,所以毫秒值并不和我们理解的一样,目前提出几个解决思路,但是SQL稍微有点长,以后想办法优化,应该有其他思路,欢迎指正。目前解决思路就是自定义函数Thinking 4

1.Thinking 1 精确到秒 TO_DATE()

赶时间直接看​​4.Thinking 4 自定义函数解析时间​​,有时间的慢慢看,4为解决办法
分三段写;
2019-05-28 23:59:59

--1559059199000
SELECT TO_NUMBER(TO_DATE('2019-05-28 23:59:59', 'YYYY-MM-DD HH24:MI:SS') -
TO_DATE('1970-01-01 8:0:0', 'YYYY-MM-DD HH24:MI:SS')) * 24 * 60 * 60 * 1000
FROM DUAL;
2019-05-29 00:01:00

--1559059260000
SELECT TO_NUMBER(TO_DATE('2019-05-29 00:01:00', 'YYYY-MM-DD HH24:MI:SS') -
TO_DATE('1970-01-01 8:0:0', 'YYYY-MM-DD HH24:MI:SS')) * 24 * 60 * 60 * 1000
FROM DUAL;
两数相减

--61000
select 1559059260000-1559059199000 from dual;

缺点

通过获取当前时间,直接日期相减,获得当天到1970年的毫秒值,but,to_date 函数只能精确到 ,误差会出现,无法精确到毫秒,但是可以精确到秒求得我们所需毫秒值

2.Thinking 2 精确到毫秒 TO_TIMESTAMP()

实时计算日期函数TO_TIMESTAMP使用链接

既然to_date函数只能精确到秒,那么,我们使用Oracle的另一个可以精确到 毫秒 的函数 to_timestamp
2019-06-06 14:13:00

--2019-06-06 14:13:00.000000000
select to_timestamp('2019-06-06 14:13:00', 'YYYY-MM-DD HH24:MI:SS.ff') from dual;
out
2019-06-06 14:13:00.000000000

模拟日期相减
2019-06-06 14:13:0.100
2019-06-06 14:10:0.200

select to_timestamp('2019-06-06 14:13:0.100', 'YYYY-MM-DD HH24:MI:SS.ff')
-to_timestamp('2019-06-06 14:10:0.200', 'YYYY-MM-DD HH24:MI:SS.ff') from dual;
out
0 0:2:59.9

缺点

算出来为时间类型,几分几秒,很精准的算法。
如果你需要时间展示为毫秒形式long类型,使用Thinking 4

3.Thinking 3 精确到毫秒 EXTRACT()

换一个函数继续做毫秒问题
​oracle中 extract() 函数----用于截取年、月、日、时、分、秒 详解链接​​

--4200
select EXTRACT(SECOND FROM(to_timestamp('2019-06-06 14:12:4.200', 'YYYY-MM-DD HH24:MI:SS.ff') )) * 1000 from dual;

缺点

这个只能计算到秒,两个时间差如果大于59秒,涉及到分钟,还是没办法,就算计算分钟,它也只会显示分钟,之后精度丢失
out
4200

4 Thinking 4 自定义函数解析时间

因为实在没有办法,所以决定自定义时间解析,Thinking 2出的时间类型 解析成毫秒
注:自定义函数可以随数据库一直存在,使用时调用即可 ?
TestSQL
我们解析Thinking 2返回的这个 0 0:2:59.9时间,然后把它截取字符串,我选择一个比较全的时间进行测试,然后把这个SQL转化为函数 传参式

select day* 24 * 60 * 60 * 1000+ hour * 60 * 60 * 1000 + min * 60 * 1000 + ss * 1000 + mi from (
select INSTR( '31 11:33:40.89', ' ' ) konggeIndex,SUBSTR('31 11:33:40.89',1,2) testIndex,
instr('31 11:33:40.89', '.', 1) - instr('31 11:33:40.89', ':', 1,2) - 1 secondIndex,
instr('31 11:33:40.89', ':', 1,2) - instr('31 11:33:40.89', ':', 1)-1 minuteIndex,
instr('31 11:33:40.89', ':', 1) - instr('31 11:33:40.89', ' ', 1)-1 hourIndex,
instr('31 11:33:40.89', ' ', 1) -1 dayIndex,
to_number(SUBSTR( '31 11:33:40.89', INSTR( '31 11:33:40.89', '.') + 1, 3)) mi,
to_number(SUBSTR( '31 11:33:40.89', INSTR( '31 11:33:40.89', ':',1,2) + 1, instr('31 11:33:40.89', '.', 1) - instr('31 11:33:40.89', ':', 1,2) - 1)) ss,
to_number(SUBSTR( '31 11:33:40.89', INSTR( '31 11:33:40.89', ':',1,1) + 1, instr('31 11:33:40.89', ':', 1,2) - instr('31 11:33:40.89', ':', 1)-1 )) min,
to_number(SUBSTR( '31 11:33:40.89', INSTR( '31 11:33:40.89', ' ') + 1 , instr('31 11:33:40.89', ':', 1) - instr('31 11:33:40.89', ' ', 1)-1) )hour,
to_number(SUBSTR( '31 11:33:40.89' , 1, (instr('31 11:33:40.89', ' ') ) )) day
from dual) time;

自定义函数编写

创建函数

CREATE OR REPLACE FUNCTION get_timestamp_cha(endtime in TIMESTAMP,
starttime in TIMESTAMP)

RETURN INTEGER


AS


str VARCHAR2(50);
misecond INTEGER;
seconds INTEGER;
minutes INTEGER;
hours INTEGER;
days INTEGER;


BEGIN

str := to_char(endtime - starttime);

misecond := to_number(SUBSTR(str, INSTR(str, '.') + 1, 3));

seconds := to_number(SUBSTR(str, INSTR(str, ':',1,2) + 1, instr(str, '.', 1) - instr(str, ':', 1,2) - 1));

minutes := to_number(SUBSTR(str, INSTR(str, ':',1,1) + 1, (instr(str, ':', 1,2) )- instr(str, ':', 1)-1 ));

hours := to_number(SUBSTR(str, INSTR(str, ' ') + 1 , (instr(str, ':', 1) )- instr(str, ' ', 1)-1));

days := to_number(SUBSTR(str, 1, INSTR(str, ' ')));

RETURN days * 24 * 60 * 60 * 1000 + hours * 60 * 60 * 1000 + minutes * 60 * 1000 + seconds * 1000 + misecond;

END;

调用函数

select get_timestamp_cha(
to_timestamp('2019-06-06 14:13:0.100', 'YYYY-MM-DD HH24:MI:SS.ff'),
to_timestamp('2019-06-06 14:10:0.200', 'YYYY-MM-DD HH24:MI:SS.ff') )
millisecond
from dual;
out


顺便测试一下自己的时间


注:也可以单独计算当前时间毫秒值,开始时间传值为1970年毫秒日期就行

至此,终于解决了日期时间差毫秒值问题 ???祝你幸福

送你一首歌:《The Nights》 Avicii / RAS​​

附图:小蓬草


有关Oracle SQL 两个日期类型毫秒值求差,日期转毫秒,时间差(ms)自定义函数解决毫秒差的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  3. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  4. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  5. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  6. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  7. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  8. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  9. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  10. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

随机推荐