Oracle SQL MIN和MAX组合来自同一个表

时间:2015-01-07 20:43:29

标签: sql oracle oracle11g oracle-sqldeveloper

我有下面提到的数据。我希望得到最大的开始消息和相应的最小或成功消息。

启动消息表
ID1     Timestamp_start_msg_recieved    date        jobid      message time in seconds
1234    5/14/2014 10:02:29              5/14/2014   abc        start 262
1234    5/14/2014 10:02:31              5/14/2014   abc        start 264
1234    5/14/2014 10:02:45              5/14/2014   abc        start 278
1234    5/14/2014 10:02:50              5/14/2014   abc        start 285
1234    5/14/2014 10:09:04              5/14/2014   abc        start 165
1234    5/14/2014 10:09:06              5/14/2014   abc        start 2167
1234    5/14/2014 10:09:16              5/14/2014   abc        start 2180
1234    5/14/2014 10:09:26              5/14/2014   abc        start 2190
1234    5/14/2014 11:45:11              5/14/2014   abc        start 8767
1234    5/14/2014 16:48:20              5/14/2014   abc        start 878
1234    5/14/2014 19:02:52              5/14/2014   abc        start 687
5678    5/14/2014 22:02:52              5/14/2014   pqr        start 501
5678    5/14/2014 23:10:40              5/14/2014   pqr        start 200
成功消息表
ID1     Timestamp_success_msg_recieved  date        jobid  message time in seconds
1234    5/14/2014 10:02:52              5/14/2014   abc    successful 290
1234    5/14/2014 10:09:32              5/14/2014   abc    successful 4280 
1234    5/14/2014 11:45:15              5/14/2014   abc    successful 8774
1234    5/14/2014 11:45:18              5/14/2014   abc    successful 8777
1234    5/14/2014 11:45:19              5/14/2014   abc    successful 8778
1234    5/14/2014 11:45:25              5/14/2014   abc    successful 8784
1234    5/14/2014 16:48:22              5/14/2014   abc    successful 880 
1234    5/14/2014 19:03:00              5/14/2014   abc    successful 699
5678    5/14/2014 22:03:00              5/14/2014   pqr    successful 250
5678    5/19/2014 14:00:16              5/19/2014   pqr    successful 400

预期结果

ID1  IMESTAMP_for_start_message TIMESTAMP_for_success_message    Date       Jobid    msg  msg start_secs success_secs
1234 5/14/2014 10:02:50         5/14/2014 10:02:52           5/14/2014  abc start success 262 290 
1234 5/14/2014 10:09:26         5/14/2014 10:09:32           5/14/2014  abc start success 2190 4280
1234 5/14/2014 11:45:11         5/14/2014 11:45:25           5/14/2014  abc start success 8767 8784
1234 5/14/2014 16:48:20         5/14/2014 16:48:22           5/14/2014  abc start success 878 880
1234 5/14/2014 19:02:52         5/14/2014 19:03:00           5/14/2014  abc start success 687 699
5678 5/14/2014 22:02:52         5/14/2014 22:03:00           5/14/2014  pqr start success 501 699
5678 5/14/2014 23:10:40         null                         5/14/2014  pqr start success 250 null
5678    null                   5/19/2014 14:00:16            5/19/2014  pqr null  success null 400

我正在寻找Max of start message和start_secs以配对min of success消息和success_secs。使用WITH子句尝试使用临时表,也使用自连接方法。下面是我的查询,但WITH子句查询返回表中整体数据的MIN。

使用的查询:

WITH DATA AS
  (SELECT MIN(smt.column13) timestamp_for_success_message
  FROM success_table1 smt, start_table2 b
     WHERE
    (SMT.id1 = b.id1)
    AND (SMT.jobid = b.jobid)
    AND (SMT.timestamp_for_success_message_recieved >= b.timestamp_for_start_message_recieved)
  )
SELECT distinct a.timestamp_for_success_message_recieved,
  b.timestamp_for_start_message_recieved,
  b.id1,
  b.jobid
FROM data a,
  start_table2 b
order by b.timestamp_start_message_recieved, a.timestamp_for_success_message_recieved, b.jobid, b.id1;

2 个答案:

答案 0 :(得分:0)

编辑:根据OP的反馈,查询对于实时数据失败。这可能是由于 GROUP BY (TRUNC(TIMESTAMP_for_start_message, 'MI'))
未正确分组" id1"和" jobID"。


对于样本数据,以下工作

WITH
LatestStart AS (
  SELECT
    MAX(TIMESTAMP_for_start_message) TIMESTAMP_for_start_message
  FROM StartMessageTable
  GROUP BY (TRUNC(TIMESTAMP_for_start_message, 'MI'))
),
LatestStartEarliestSuccess AS (
  SELECT
    LS.TIMESTAMP_for_start_message
    , (SELECT MIN(TIMESTAMP_success_msg_received)
       FROM SuccessMessageTable
       WHERE
         (id1 = StMT.id1)
         AND (someDate = StMT.someDate)
         AND (jobID = StMT.jobID)
         AND (TIMESTAMP_success_msg_received >= StMT.TIMESTAMP_for_start_message)) TIMESTAMP_for_success_message
  FROM LatestStart LS
  JOIN StartMessageTable StMT
    ON LS.TIMESTAMP_for_start_message = StMT.TIMESTAMP_for_start_message
),
Detail AS (
  SELECT
    StMT.id1
    , LSES.TIMESTAMP_for_start_message
    , LSES.TIMESTAMP_for_success_message
    , StMT.jobID
    , 'start' msgStart
    , 'success' msgSuccess
    , StMT.time_in_seconds start_secs
    , SuMT.time_in_seconds success_secs
  FROM LatestStartEarliestSuccess LSES
  JOIN StartMessageTable StMT
    ON LSES.TIMESTAMP_for_start_message = StMT.TIMESTAMP_for_start_message
  LEFT JOIN SuccessMessageTable SuMT
    ON LSES.TIMESTAMP_for_success_message = SuMT.TIMESTAMP_success_msg_received
  ORDER BY LSES.TIMESTAMP_for_start_message
)
SELECT
  * FROM Detail
;

除了" start_secs"中的第一个和最后一个值列 - 但是,它似乎偏离了样本输入。
SQL Fiddle


编辑: IIF 各自的"时间戳"和"第二"值-across tables-正确参考时间点,用于组合" id1"和" jobID",以下提供了另一个起点:

SELECT DISTINCT
  id1
  , jobID
  , message
--  , TO_CHAR(TIMESTAMP_for_start_message, 'YYYY-MM-DD HH24:MI:SS') timestamp
  , TO_CHAR(TIMESTAMP_for_start_message - NUMTODSINTERVAL(time_in_seconds, 'SECOND'), 'YYYY-MM-DD HH24:MI:SS') job_start_time
--  , time_in_seconds
FROM StartMessageTable
UNION ALL
SELECT DISTINCT
  id1
  , jobID
  , message
--  , TO_CHAR(TIMESTAMP_success_msg_received, 'YYYY-MM-DD HH24:MI:SS') timestamp
  , TO_CHAR(TIMESTAMP_success_msg_received - NUMTODSINTERVAL(time_in_seconds, 'SECOND'), 'YYYY-MM-DD HH24:MI:SS') job_start_time
--  , time_in_seconds
FROM SuccessMessageTable
ORDER BY id1, jobID, 4, message;

但是,使用LEAD方法(在此问题的另一个答案中给出)返回通缉,可能不值得进一步研究该选项。

答案 1 :(得分:0)

对于样本数据,以下也适用

WITH
RawData AS (
  SELECT
    id1
    , jobID
    , message
    , TIMESTAMP_for_start_message timeStamp
    , time_in_seconds
  FROM StartMessageTable
  UNION ALL
  SELECT
    id1
    , jobID
    , message
    , TIMESTAMP_success_msg_received
    , time_in_seconds
  FROM SuccessMessageTable
  ORDER BY id1, jobID, 4
),
Detail AS (
  SELECT
    id1
    , jobID
    , message message1
    , LEAD (message, 1) OVER (ORDER BY id1, jobID, timeStamp) message2
    , timeStamp timeStamp1
    , LEAD (timeStamp, 1) OVER (ORDER BY id1, jobID, timeStamp) timeStamp2
    , time_in_seconds secs1
    , LEAD (time_in_seconds, 1) OVER (ORDER BY id1, jobID, timeStamp) secs2
  FROM RawData
)
SELECT
  id1
  , timeStamp1 TIMESTAMP_for_start_message
  , timeStamp2 TIMESTAMP_for_success_message
  , jobID
  , 'start' msgStart
  , 'success' msgSuccess
  , secs1 start_secs
  , secs2 success_secs
FROM Detail
WHERE (message1 = 'start' AND message2 = 'successful') OR message2 IS NULL
ORDER BY timeStamp1
;

对“start_secs”列中的第一个和最后一个值有相同的警告 SQL Fiddle