问题
I have below mentioned data. I am looking to get max of Start message and corresponding min or success message.
Start Message TableID1 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
Success Message Table
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
Expected Result
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
I am looking for Max of start message and start_secs to pair up with min of success message and success_secs. Tried using Temporary table using WITH clause and also used self join method. Below is my query, But WITH clause query returns MIN of overall data in the table.
Query Used:
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;
回答1:
For the sample data, the following works as well
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
;
with the same caveat regarding the first and last value in the "start_secs" column.
SQL Fiddle
回答2:
Edit: According to OP's feedback, the query fails for the live data. This is likely due toGROUP BY (TRUNC(TIMESTAMP_for_start_message, 'MI'))
not correctly grouping the records for "id1" and "jobID".
For the sample data the following works
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
;
except for the first and last value in the "start_secs" column - which, however, seem to deviate from the sample input.
SQL Fiddle
Edit: IIF the respective "timestamp" and "second" values do -across tables- correctly reference points in time for combinations of "id1" and "jobID", the following provides an alternative starting point:
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;
However, with the LEAD
approach (given in another answer to this question) returning the wanted, it's probably not worth to look further into that option.
来源:https://stackoverflow.com/questions/27828293/oracle-sql-min-and-max-combination-from-same-table