ORACLE SQL根据其他表中的值从1个表中检索记录

时间:2014-10-09 21:25:04

标签: sql oracle

我有3张桌子:

-Table:Periods - Fields:Period_ID,Member_name,Start_time,Finish_time,Period_Timeouts

-Table:PeriodTimeouts - 字段:Timeout_ID,Period_ID,Start_time,Finish_time

-Table:超时 - 字段:Timeout_ID,Start_time,Finish_time,Member_name

它们之间的唯一联系如下:

-A Periods记录可能包含0个或更多PeriodTimeouts。因此,Periods中的记录将在其Period_Timeouts字段中包含0个或多个Timeout_ID。

- 每个PeriodTimeouts记录都有它所链接的Period的ID以及它所代表的Timeouts记录的ID。

我需要找到所有没有PeriodTimeout但有超时记录的Period,它们属于同一时间范围,并且适用于同一个Member_name。

请注意,如果Timeouts记录时间范围的任何部分落在Periods记录的时间范围内,那么Periods记录或Timeout记录的时间范围不必相同。

我尝试了以下内容:

SELECT
  PERIODS.PERIOD_ID,
  PERIODS.MEMBER_NAME,
  PERIODS.START_TIME,
  PERIODS.FINISH_TIME
FROM
  PERIODS,
  PERIODTIMEOUTS
WHERE
  PERIODS.PERIOD_ID=PERIODTIMEOUTS.PERIOD_ID(+)
  AND  
  PERIODS.FINISH_TIME  <  '2014-10-09 00:00:00'
  AND
  PERIODS.FINISH_TIME  >=  '2014-10-08 00:00:00'
  AND
  (SELECT COUNT(TIMEOUTS.TIMEOUT_ID) FROM TIMEOUTS
     WHERE
        TIMEOUTS.MEMBER_NAME = PERIODS.MEMBER_NAME AND
        TIMEOUTS.FINISH_TIME >= PERIODS.START_TIME AND
        TIMEOUTS.START_TIME <= PERIODS.FINISH_TIME) > 0

但查询执行的时间太长,以至于我认为它没有工作(我已经等了大约10分钟而且还在处理)但请注意,表格有很多数据的。每天大约有2000个时期,数据可以追溯到3年左右。

示例数据:

PERIODS(PERIODS_ID,MEMBER_NAME,START_TIME,FINISH_TIME)

1,DTW234,2014-10-09 01:05:54,2014-10-09 01:15:54

2,DTX432,2014-10-09 01:25:32,2014-10-09 02:15:51

3,DTW211,2014-10-09 01:34:43,2014-10-09 01:36:42

4,DTW002,2014-10-09 01:45:12,2014-10-09 03:54:45

PERIODTIMEOUTS(TIMEOUT_ID,PERIOD_ID,START_TIME,FINISH_TIME)

3,1,2014-10-09 00:01:36,2014-10-09 01:06:27

4,4,2014-10-09 01:50:01,2014-10-09 02:32:38

TIMEOUTS(TIMEOUT_ID,MEMBER_NAME,START_TIME,FINISH_TIME)

1,DTX432,2014-10-08 23:01:35,2014-10-09 01:26:17

2,DTW211,2014-10-08 20:21:52,2014-10-09 01:00:17

3,DTW234,2014-10-09 00:01:36,2014-10-09 01:06:27

4,DTW002,2014-10-09 01:50:01,2014-10-09 02:32:38

预期结果

1,DTW234,2014-10-09 01:05:54,2014-10-09 01:15:54

结果说明

  • 结果应该是Periods表中的记录。
  • 时段1是存在超时记录(超时3)的唯一时段,其中Member_name相同,TIMEOUT的时间范围覆盖PERIOD的某些时间范围,并且TIMEOUT没有PERIODTIMEOUTS记录
  • 期间3不包含在结果中,因为虽然它在PERIODTIMEOUTS中没有任何匹配的记录,但没有TIMEOUT的时间范围涵盖某些PERIOD时间范围。

1 个答案:

答案 0 :(得分:1)

尝试:

select p.period_id,
       p.member_name,
       p.start_time,
       p.finish_time,
       count(*) as num_timeouts
  from periods p
  join timeouts t
    on p.member_name = t.member_name
   and t.finish_time >= p.start_time
   and t.start_time <= p.finish_time
  left join periodtimeouts pt
    on p.period_id = pt.period_id
 where p.finish_time < '2014-10-09 00:00:00'
   and p.finish_time >= '2014-10-08 00:00:00'
   and pt.period_id is null
 group by p.period_id, p.member_name, p.start_time, p.finish_time