简体   繁体   中英

Oracle 12c - sql to find out of order rows

I have a table with following columns:

FILE_NAME VARCHAR2(30);
STATUS VARCHAR2(2);
DEPT_ID NUMBER;
DEPT_SUB_ID NUMBER;
CREATE_DATE DATE;

sample data:

FILE_NAME                 STATUS  DEPT_ID   DEPT_SUB_ID  CREATE_DATE
---------                 ------- --------  -----------  ----------
TEST_20180806222127       C       1         10           07-AUG-18 01.04.47.821795000 AM
TEST_20180806221940       C       1         10           07-AUG-18 04.12.20.957400000 AM
TEST_20180806221733       C       1         10           07-AUG-18 03.35.27.809494000 AM
TEST_20180805202020       C       1         20           06-AUG-18 02.24.47.821795000 AM
TEST_20180805201640       C       1         20           06-AUG-18 00.42.20.957400000 AM
TEST_20180805201530       C       1         20           06-AUG-18 03.55.27.809494000 AM

FILE_NAME consists of: <TYPE>_<DATETIME> I want to write a query for each DEPT_ID , DEPT_SUB_ID to determine which files with STATUS = 'C' were created out of order based on the <DATETIME> on FILE_NAME and CREATE_DATE field. In this example, for DEPT_SUB_ID = 10 , file TEST_20180806222127 was created before the other 2 based on the DATE_TIME on the file name so I would need to return only this file name in result for DEPT_SUB_ID = 10 . For DEPT_SUB_ID = 20 , result should contain TEST_20180805201640 and TEST_20180805202020 since both were created before TEST_20180805201530 , which is considered out of order.

Expected results from query will output all file_name's which were created before it's order of run.

You can assign two rankings to each row, one based on the order of the timestamp embedded int he file name, or other on the order of the creation date:

select yt.*,
  row_number() over (partition by dept_id, dept_sub_id
    order by to_date(substr(file_name, -14), 'YYYYMMDDHH24MISS')) as rn_file_name,
  row_number() over (partition by dept_id, dept_sub_id
    order by create_date) as rn_create_date
from your_table yt;

FILE_NAME           S    DEPT_ID DEPT_SUB_ID CREATE_DATE                   RN_FILE_NAME RN_CREATE_DATE
------------------- - ---------- ----------- ----------------------------- ------------ --------------
TEST_20180806221733 C          1          10 2018-08-07 03:35:27.809494000            1              2
TEST_20180806221940 C          1          10 2018-08-07 04:12:20.957400000            2              3
TEST_20180806222127 C          1          10 2018-08-07 01:04:47.821795000            3              1
TEST_20180805201530 C          1          20 2018-08-06 03:55:27.809494000            1              3
TEST_20180805201640 C          1          20 2018-08-06 00:42:20.957400000            2              1
TEST_20180805202020 C          1          20 2018-08-06 02:24:47.821795000            3              2

Then filter to see the mismatches:

select file_name, status, dept_id, dept_sub_id, create_date
from (
  select yt.*,
    row_number() over (partition by dept_id, dept_sub_id
      order by to_date(substr(file_name, -14), 'YYYYMMDDHH24MISS')) as rn_file_name,
    row_number() over (partition by dept_id, dept_sub_id
      order by create_date) as rn_create_date
  from your_table yt
)
where rn_file_name > rn_create_date;

FILE_NAME           S    DEPT_ID DEPT_SUB_ID CREATE_DATE                  
------------------- - ---------- ----------- -----------------------------
TEST_20180806222127 C          1          10 2018-08-07 01:04:47.821795000
TEST_20180805201640 C          1          20 2018-08-06 00:42:20.957400000
TEST_20180805202020 C          1          20 2018-08-06 02:24:47.821795000

And you can add a filter for a specific ID or sub-ID, either in the inner or outer query, if you don't want to see them all at once.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM