I have two tables bc_transactions & bc_messages. I used the below query to join these two tables
SELECT distinct(bt.USER_TRANS_ID),bm.TS,bm.STATUS FROM bc_transactions bt inner JOIN bc_messages bm ON bt.USER_TRANS_ID=bm.USER_MESSAGE_ID where bt.protocol_name = 'Gateway' and bt.STATUS=bm.STATUS AND bt.startdate >=TRUNC(SYSDATE-2) AND bt.startdate <=TRUNC(SYSDATE-1) AND bt.STATUS like 'ERROR TRANSPORT' AND bt.HOSTNAME='HEB' order by bt.USER_TRANS_ID ASC;
the bc_messages table has multiple rows with status as ERROR TRANSPORT which have the same USER_MESSAGE_ID at different timestamp(bm.TS). I am trying to get only the latest row.
|USER_TRANS_ID | TS | STATUS | ------------------------------------------------------------- | ID1 | 10-03-2020 15:01:23 | ERROR TRANSPORT | | ID1 | 10-03-2020 15:15:23 | ERROR TRANSPORT | | ID1 | 10-03-2020 15:30:23 | ERROR TRANSPORT | | ID1 | 10-03-2020 15:35:23 | ERROR TRANSPORT | | ID2 | 10-03-2020 16:10:23 | ERROR TRANSPORT | | ID2 | 10-03-2020 16:11:23 | ERROR TRANSPORT |
Advertisement
Answer
You can use row_number()
:
select t.* from (select bt.USER_TRANS_ID, bm.TS,bm.STATUS, row_number() over (partition by bt.USER_TRANS_ID order by bm.TS desc) as seq from bc_transactions bt inner join bc_messages bm on bt.USER_TRANS_ID = bm.USER_MESSAGE_ID where bt.protocol_name = 'Gateway' and bt.STATUS=bm.STATUS and bt.startdate >= TRUNC(SYSDATE-2) and bt.startdate <= TRUNC(SYSDATE-1) and bt.STATUS like 'ERROR TRANSPORT' and bt.HOSTNAME = 'HEB' ) t where seq = 1;