Создание запроса SQL для точного определения записи в стеке на основе «статуса» и его хронологического порядка - PullRequest
0 голосов
/ 08 октября 2019

Я пытаюсь выяснить, как построить запрос, который будет возвращать только 2 из записей транзакций из стека 1 во многие записи транзакций, сгруппированные под одним серийным номером. 2 записи, которые мне нужны;

1) самая последняя транзакция в стеке, которая имеет статус «ОШИБКА» и 2) следующая самая последняя транзакция в этом стеке, которая имеет статус «УСПЕХ».

Так чтоПример набора записей может выглядеть следующим образом ...

1)  SERIAL_NUMBER   TRXN_ID     STATUS
    -------------   ---------   --------
1   08LKL47T8ZF6    16379796    Success
2   08LKL47T8ZF6    16380200    Error
3   08LKL47T8ZF6    16381077    Retired
4   08LKL47T8ZF6    16581500    Success
5   08LKL47T8ZF6    16581833    Success
6   08LKL47T8ZF6    16382800    Retired
7   08LKL47T8ZF6    16583505    Error
8   08LKL47T8ZF6    16586413    Error

Пока у меня есть следующее ... но это вернет все 8 записей, перечисленных выше ...

SELECT 
         STG.src_serial_number 
        ,STG.trxn_id
        ,STG.interface_status
  FROM 
       staging_table STG 

       -- All SN's where the most recent(max) transaction was an ERROR.
       ,(  SELECT X.src_serial_number
             FROM staging_table X  
                  ,(  SELECT MAXNUM.src_serial_number, max(MAXNUM.trxn_id) as trxn_id
                        FROM staging_table MAXNUM  
                       WHERE MAXNUM.src_serial_number = src_serial_number
                    GROUP BY MAXNUM.src_serial_number ) Y
            WHERE X.src_serial_number = Y.src_serial_number
              AND X.trxn_id = Y.trxn_id
              AND X.interface_status = 'Error'
        ) ERROR_REC

       -- No prior TRXN_ID / trxn for this Serial Number stack is a SUCCESS.
       ,(  SELECT PRIORSUCCESS.src_serial_number
             FROM staging_table PRIORSUCCESS
            WHERE PRIORSUCCESS.interface_status = 'Success' 
              AND PRIORSUCCESS.src_serial_number = src_serial_number
        ) SUCCESS_REC

 WHERE STG.src_serial_number = ERROR_REC.src_serial_number
   AND STG.src_serial_number = SUCCESS_REC.src_serial_number
   AND ERROR_REC.src_serial_number = SUCCESS_REC.src_serial_number

ORDER BY  STG.src_serial_number asc, STG.trxn_id asc

Ожидаемые результаты будут заключаться в создании запроса, который будет возвращать только записи № 8 (последняя ошибка) и № 5 (последний успех)

    SERIAL_NUMBER   TRXN_ID     STATUS
    -------------   ---------   --------
5   08LKL47T8ZF6    16581833    Success
8   08LKL47T8ZF6    16586413    Error

Ответы [ 2 ]

0 голосов
/ 12 октября 2019

спасибо за отзыв. @LittleFoot, я думаю, что вышеприведенное решение нереально, если я не понимаю его неправильно. Моя таблица, из которой мне нужно получить данные (STAGING_TABLE), содержит 9,5 миллионов строк и растет с каждым днем. Объединение каждой строки данных было бы невозможно. Это то, что я построил до сих пор, но это слишком медленно ...

  SELECT STG_SUB.src_serial_number
    FROM staging_table STG_SUB
   WHERE STG_SUB.interface_status = 'Error'
     AND STG_SUB.record_id = ( SELECT MAX(MAX_TRXN.record_id)
                                 FROM staging_table MAX_TRXN
                                WHERE MAX_TRXN.src_serial_number = STG_SUB.src_serial_number )
UNION
  SELECT STG_SUB.src_serial_number
    FROM staging_table STG_SUB
   WHERE STG_SUB.record_id = ( SELECT MAX(MAX_TRXN.record_id)
                                 FROM staging_table MAX_TRXN
                                WHERE MAX_TRXN.src_serial_number = STG_SUB.src_serial_number
                                  AND MAX_TRXN.interface_status = 'Success'
MINUS
  SELECT STG_SUB.src_serial_number
    FROM staging_table STG_SUB
   WHERE STG_SUB.interface_status <> 'Error'
     AND STG_SUB.record_id = ( SELECT MAX(MAX_TRXN.record_id)
                                 FROM staging_table MAX_TRXN
                                WHERE MAX_TRXN.src_serial_number = STG_SUB.src_serial_number )
ORDER BY 1
0 голосов
/ 08 октября 2019

Не слишком красиво, но - это поможет? Вероятно, не будет работать слишком быстро, если набор данных большой (учтите, что вы извлекаете данные из одной и той же таблицы 3 раза!).

SQL> with test (rn, serial, trxn_id, status) as
  2  (
  3  select 1,   '08LKL47T8ZF6',    16379796,    'Success' from dual union all
  4  select 2,   '08LKL47T8ZF6',    16380200,    'Error'   from dual union all
  5  select 3,   '08LKL47T8ZF6',    16381077,    'Retired' from dual union all
  6  select 4,   '08LKL47T8ZF6',    16581500,    'Success' from dual union all
  7  select 5,   '08LKL47T8ZF6',    16581833,    'Success' from dual union all
  8  select 6,   '08LKL47T8ZF6',    16382800,    'Retired' from dual union all
  9  select 7,   '08LKL47T8ZF6',    16583505,    'Error'   from dual union all
 10  select 8,   '08LKL47T8ZF6',    16586413,    'Error'   from dual
 11  )
 12  select * from test
 13  where trxn_id = (select max(trxn_id) from test
 14                   where status = 'Error'
 15                  )
 16     or trxn_id = (select max(trxn_id) from test
 17                   where status = 'Success'
 18                     and trxn_id < (select max(trxn_id) from test
 19                                    where status = 'Error'
 20                                   )
 21                  );

        RN SERIAL          TRXN_ID STATUS
---------- ------------ ---------- -------
         5 08LKL47T8ZF6   16581833 Success
         8 08LKL47T8ZF6   16586413 Error

SQL>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...