简体   繁体   English

有没有更好的方法来编写这个Oracle SQL来处理两个不同列中的日期比较?

[英]Is there a better way to write this Oracle SQL that deals with comparing dates in two different columns?

For a table in an Oracle 11g database: 对于Oracle 11g数据库中的表:

CREATE TABLE mytable (START_DATE_TIME DATE, END_DATE_TIME DATE);
Insert into MYTABLE (START_DATE_TIME,END_DATE_TIME) values (to_date('06/20/2013 01:30:00 PM','MM/DD/YYYY HH:MI:SS AM'),to_date('06/20/2013 06:15:00 PM','MM/DD/YYYY HH:MI:SS AM'));
Insert into MYTABLE (START_DATE_TIME,END_DATE_TIME) values (to_date('06/21/2013 06:45:00 PM','MM/DD/YYYY HH:MI:SS AM'),to_date('06/22/2013 06:45:00 AM','MM/DD/YYYY HH:MI:SS AM'));
Insert into MYTABLE (START_DATE_TIME,END_DATE_TIME) values (to_date('06/23/2013 06:45:00 AM','MM/DD/YYYY HH:MI:SS AM'),to_date('06/23/2013 10:30:00 PM','MM/DD/YYYY HH:MI:SS AM'));
Insert into MYTABLE (START_DATE_TIME,END_DATE_TIME) values (to_date('06/25/2013 08:00:00 AM','MM/DD/YYYY HH:MI:SS AM'),to_date('06/25/2013 05:30:00 PM','MM/DD/YYYY HH:MI:SS AM'));
Insert into MYTABLE (START_DATE_TIME,END_DATE_TIME) values (to_date('06/25/2013 05:30:00 PM','MM/DD/YYYY HH:MI:SS AM'),to_date('06/26/2013 05:30:00 AM','MM/DD/YYYY HH:MI:SS AM'));
START_DATE_TIME         END_DATE_TIME
06/20/2013 01:30:00 PM  06/20/2013 06:15:00 PM
06/21/2013 06:45:00 PM  06/22/2013 06:45:00 AM
06/23/2013 06:45:00 AM  06/23/2013 10:30:00 PM
06/25/2013 08:00:00 AM  06/25/2013 05:30:00 PM
06/25/2013 05:30:00 PM  06/26/2013 05:30:00 AM

My goal is to find the hours between END_DATE_TIME and the next most recent START_DATE_TIME. 我的目标是找到END_DATE_TIME和下一个最近的START_DATE_TIME之间的小时数。

My query is : 我的查询是:

SELECT start_date_time,
  end_date_time,
  ROUND((next_start_date - end_date_time)*24,2) hours_to_next_start
FROM
  (SELECT t.start_date_time,
    t.end_date_time,
    (SELECT MIN(t2.start_date_time)
    FROM mytable t2
    WHERE t2.start_date_time >= t.end_date_time
    ) next_start_date
  FROM mytable t
  ORDER BY t.start_date_time
  )

and I get the results: 我得到了结果:

START_DATE_TIME         END_DATE_TIME           HOURS_TO_NEXT_START 
06/20/2013 01:30:00 PM  06/20/2013 06:15:00 PM  24.5
06/21/2013 06:45:00 PM  06/22/2013 06:45:00 AM  24
06/23/2013 06:45:00 AM  06/23/2013 10:30:00 PM  33.5
06/25/2013 08:00:00 AM  06/25/2013 05:30:00 PM  0
06/25/2013 05:30:00 PM  06/26/2013 05:30:00 AM  NULL

It works fine as far as I know. 据我所知,它工作得很好。 But something tells me there might be a better, or at least newer, way to do this without the secondary query in the select? 但有些事情告诉我,如果没有select中的二级查询,可能会有更好的,或者至少更新的方式来做到这一点?

What do you say? 你说什么?

There is a more "modern" way to do this, using the analytic LEAD function. 使用分析LEAD功能,有一种更“现代”的方法。 I think it's better because it's more compact, plus once you get used to the analytic functions you'll find them easy to read - but that's just an opinion :) 我认为它更好,因为它更紧凑,加上一旦你习惯了分析功能,你会发现它们很容易阅读 - 但这只是一个意见:)

SELECT
  Start_Date_Time,
  End_Date_Time,
  ROUND((next_start_date - end_date_time)*24,2) hours_to_next_start
FROM (
  SELECT
    Start_Date_Time,
    End_Date_Time,
    LEAD(Start_Date_Time) OVER (ORDER BY Start_Date_Time) AS   Next_Start_Date
  FROM myTable
)
ORDER BY Start_Date_Time

There's a SQL Fiddle here . 有一个SQL小提琴这里 To get more insight into how this works, try running the inner query on its own. 要更深入地了解其工作原理,请尝试单独运行内部查询。

Use this query for getting diff hours between two date this will return as HH.MM 使用此查询获取两个日期之间的差异时间,这将作为HH.MM返回

SELECT 
CONCAT
(
 DATEDIFF(MI,'06/20/2013 01:30:00 PM','06/20/2013 06:15:00 PM') / 60 ,'.', DATEDIFF(MI,'06/20/2013 01:30:00 PM','06/20/2013 06:15:00 PM') % 60
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM