将记录从第一天发生到第二天的第一次发生?

时间:2013-12-20 03:53:01

标签: oracle

我有一个非常简单的表,它记录了事件类型(#1到#9)的时间戳和转移(days-1,swing-2,grave-3)。我想运行一个查询,该查询向我提供从一天的第一天班次事件到第二天的第一天班次事件的所有事件。

类似的东西:

select date_dt,event_type,shift 
  from my_table 
where *first occurance* shift#1 and date_dt = *some date*
to
select date_dt,event_type,shift 
    from my_table 
where *first occurance* shift#1 and date_dt = *the next day*`<code>

这会是某种类型的声明或联盟......只是不确定如何返回昨天从第一个事件开始并在今天第一个事件处停止的查询?

感谢您的帮助。

克里斯

2 个答案:

答案 0 :(得分:0)

您需要介于操作符

之后
select date_dt,event_type,shift
from mytable
where date_dt between '19-DEC-2013' and 
    to_date('19-DEC-2013 23:59:59', 'DD-MON-YYYY HH24:MI:SS');
'19 -DEC-2013'是12月19日的第一秒,'19 -DEC-2013 23:59:59'是当天的最后一秒。 正如您所表达的那样,您希望第二天没有记录,所有可能的记录来自'19-DEC-2013' - 示例日期。

答案 1 :(得分:0)

如果您有一个包含每个班次的预期开始和结束时间的表格:

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE my_table ( date_dt,event_type,shift ) AS
          SELECT TO_TIMESTAMP ('20-Dec-13 03:23:17.010000', 'DD-Mon-RR HH24:MI:SS.FF'), '2013-12-19 Event 7', 'Security Shift 2' FROM DUAL
UNION ALL SELECT TO_TIMESTAMP ('20-Dec-13 04:59:59.010000', 'DD-Mon-RR HH24:MI:SS.FF'), '2013-12-19 Event 8', 'Security Shift 2' FROM DUAL
UNION ALL SELECT TO_TIMESTAMP ('20-Dec-13 05:30:17.010000', 'DD-Mon-RR HH24:MI:SS.FF'), '2013-12-19 Time Out', 'Security Shift 2' FROM DUAL
UNION ALL SELECT TO_TIMESTAMP ('20-Dec-13 23:29:10.123000', 'DD-Mon-RR HH24:MI:SS.FF'), '2013-12-20 Time In', 'Security Shift 2' FROM DUAL
UNION ALL SELECT TO_TIMESTAMP ('20-Dec-13 23:59:22.111100', 'DD-Mon-RR HH24:MI:SS.FF'), '2013-12-20 Event 1', 'Security Shift 2' FROM DUAL
UNION ALL SELECT TO_TIMESTAMP ('21-Dec-13 00:00:00.000000', 'DD-Mon-RR HH24:MI:SS.FF'), '2013-12-20 Event 2', 'Security Shift 2' FROM DUAL
UNION ALL SELECT TO_TIMESTAMP ('21-Dec-13 02:17:23.333300', 'DD-Mon-RR HH24:MI:SS.FF'), '2013-12-20 Event 3', 'Security Shift 2' FROM DUAL
UNION ALL SELECT TO_TIMESTAMP ('21-Dec-13 04:30:10.444400', 'DD-Mon-RR HH24:MI:SS.FF'), '2013-12-20 Event 4', 'Security Shift 2' FROM DUAL
UNION ALL SELECT TO_TIMESTAMP ('21-Dec-13 05:01:07.123000', 'DD-Mon-RR HH24:MI:SS.FF'), '2013-12-20 Time Out', 'Security Shift 2' FROM DUAL
UNION ALL SELECT TO_TIMESTAMP ('21-Dec-13 23:30:15.123000', 'DD-Mon-RR HH24:MI:SS.FF'), '2013-12-21 Time In', 'Security Shift 2' FROM DUAL
UNION ALL SELECT TO_TIMESTAMP ('21-Dec-13 23:59:59.999999', 'DD-Mon-RR HH24:MI:SS.FF'), '2013-12-21 Event 1', 'Security Shift 2' FROM DUAL
UNION ALL SELECT TO_TIMESTAMP ('22-Dec-13 00:10:00.000000', 'DD-Mon-RR HH24:MI:SS.FF'), '2013-12-21 Event 2', 'Security Shift 2' FROM DUAL
UNION ALL SELECT TO_TIMESTAMP ('22-Dec-13 01:11:11.111111', 'DD-Mon-RR HH24:MI:SS.FF'), '2013-12-21 Event 3', 'Security Shift 2' FROM DUAL
UNION ALL SELECT TO_TIMESTAMP ('22-Dec-13 04:45:45.454545', 'DD-Mon-RR HH24:MI:SS.FF'), '2013-12-21 Event 4', 'Security Shift 2' FROM DUAL;

-- Shift 2 is expected to start at 23:30:00 on the current day and finish at 05:00:00 on the next day.
CREATE TABLE shift_times ( shift, start_time, end_time ) AS
SELECT 'Security Shift 2', TO_DSINTERVAL( '0 23:30:00' ),  TO_DSINTERVAL( '1 5:00:00' ) FROM DUAL

查询1

-- Find the mid-point of the shift and subtract half-a-day
-- then shift the times so that the event times are an offset
-- from that time. This is used so that the "shifted times" for
-- each shift are all on the same day - even if a shift crosses
-- a day boundary.
WITH shifted_dates AS (
  SELECT date_dt - ( start_time + end_time )/2  + TO_DSINTERVAL( '0 12:00:00' ) AS shifted_date,
         date_dt,
         m.shift,
         event_type
  FROM   my_table m
         INNER JOIN
         shift_times s
         ON ( m.shift = s.shift )
  WHERE  m.shift = 'Security Shift 2'
),
-- Extract the year-month-day of the shift and conver it to a date.
days AS (
  SELECT TO_DATE( EXTRACT( YEAR FROM shifted_date )
                   || '-' || EXTRACT ( MONTH FROM shifted_date )
                   || '-' || EXTRACT ( DAY FROM shifted_date )
                 , 'YYYY-MM-DD' ) AS day,
         date_dt,
         shift,
         event_type
  FROM   shifted_dates
)
-- Select the events for the required day
-- plus the first event of the following day.
SELECT date_dt,
       shift,
       event_type
FROM   days
WHERE  day = TO_DATE( '2013-12-20', 'YYYY-MM-DD' )
UNION ALL
SELECT MIN( date_dt    ) KEEP ( DENSE_RANK FIRST ORDER BY date_dt ),
       MIN( shift      ) KEEP ( DENSE_RANK FIRST ORDER BY date_dt ),
       MIN( event_type ) KEEP ( DENSE_RANK FIRST ORDER BY date_dt )
FROM   days
WHERE  day = TO_DATE( '2013-12-20', 'YYYY-MM-DD' ) + INTERVAL '1' DAY
ORDER BY date_dt

<强> Results

|                         DATE_DT |            SHIFT |          EVENT_TYPE |
|---------------------------------|------------------|---------------------|
| December, 20 2013 23:29:10+0000 | Security Shift 2 |  2013-12-20 Time In |
| December, 20 2013 23:59:22+0000 | Security Shift 2 |  2013-12-20 Event 1 |
| December, 21 2013 00:00:00+0000 | Security Shift 2 |  2013-12-20 Event 2 |
| December, 21 2013 02:17:23+0000 | Security Shift 2 |  2013-12-20 Event 3 |
| December, 21 2013 04:30:10+0000 | Security Shift 2 |  2013-12-20 Event 4 |
| December, 21 2013 05:01:07+0000 | Security Shift 2 | 2013-12-20 Time Out |
| December, 21 2013 23:30:15+0000 | Security Shift 2 |  2013-12-21 Time In |

如果您没有班次开始和结束时间表,那么您可以将其作为绑定变量传递给查询。