我确信这是一个很容易解决的问题,但是无论我怎么看,我都看不出它是怎么回事。
我正在使用Oracle数据库,我正在尝试报告处理时间。系统正在运行一个进程,该进程将传入的文件和进程接收到数据库中。在执行此任务时,它会记录每个不同部分的发生时间以及来自哪个部分。我已经过滤了数据,只是给我开始和结束时间,因为这是我目前感兴趣的。示例数据
integer(c_int) function cudaMalloc(devPtr, size) bind(C,name="cudaMalloc")
use iso_c_binding
type(c_ptr) :: devPtr
integer(c_size_t), value :: size
end function
我想要得到的是每个"套装的持续时间" (开始时间到结束时间)。当一天只有一次出现时很容易,但是当看到像16日这样的日子,在一天中有两套,或者从19日开始到20日结束时,我正在努力。我知道这在编程语言中是可能的,但我相信在Oracle中也必须是可能的。
我希望从上面得到的输出是:
5 15/MAY/15 00:37:01 Started
5 15/MAY/15 00:50:45 Finished
5 16/MAY/15 02:07:41 Started
5 16/MAY/15 02:19:16 Finished
5 16/MAY/15 23:20:25 Started
5 16/MAY/15 23:28:53 Finished
5 17/MAY/15 23:16:36 Started
5 17/MAY/15 23:27:51 Finished
5 18/MAY/15 23:31:28 Started
5 18/MAY/15 23:47:41 Finished
5 19/MAY/15 23:44:12 Started
5 20/MAY/15 00:06:17 Finished
5 20/MAY/15 23:33:42 Started
5 20/MAY/15 23:58:16 Finished
谢谢,
答案 0 :(得分:3)
正如Patrick Bacon在评论中提到的那样,您可以使用前导和滞后analytic functions来查看每一行的前后。如果您正在查看的行是“已启动”,那么您需要在下一行(按时间顺序,对于相同的源)达到峰值,以使用lead
获取匹配的“已完成”行。相反,如果您正在查看的行是“已完成”,那么您需要在上一行达到峰值,以使用lag
获得匹配的“已启动”行:
select distinct source,
case when action = 'Started' then time
else lag(time) over (partition by source order by time) end as starttime,
case when action = 'Finished' then time
else lead(time) over (partition by source order by time) end as endtime
from t
order by source, starttime;
SOURCE STARTTIME ENDTIME
---------- ------------------- -------------------
5 2015-05-15 00:37:01 2015-05-15 00:50:45
5 2015-05-16 02:07:41 2015-05-16 02:19:16
5 2015-05-16 23:20:25 2015-05-16 23:28:53
5 2015-05-17 23:16:36 2015-05-17 23:27:51
5 2015-05-18 23:31:28 2015-05-18 23:47:41
5 2015-05-19 23:44:12 2015-05-20 00:06:17
5 2015-05-20 23:33:42 2015-05-20 23:58:16
因为你正在寻找前后,你最终会得到重复的数据对;在这里,我使用distinct
来压缩这些重复项,但您也可以将其用作子查询并过滤结果。
SQL Fiddle可提供您的样本数据。
答案 1 :(得分:2)
功能lead()的解决方案:
select tsource, starttime, endtime
from (
select tsource, ttime starttime, status,
lead(ttime) over (partition by tsource order by ttime) endtime
from test)
where status = 'Started'
编辑: 如果可能发生两行,其状态为已启动,并且之间没有已完成 那么你需要一些防止这种情况的保护,例如这显示为null:
select tsource, starttime, endtime
from (
select tsource, ttime starttime, status,
case when lead(status) over (partition by tsource order by ttime) = 'Finished'
then lead(ttime) over (partition by tsource order by ttime)
else null
end endtime
from test)
where status = 'Started'