Я новичок в Oracle. У меня есть требование, по которому мне нужно получить все коды ошибок из поля комментария, а затем проверить их в другой таблице, чтобы увидеть тип кода. В зависимости от типа кода я должен отдавать предпочтение конкретному типу, а затем отображать этот код ошибки и вводить его в CSV вместе с другими столбцами. Ниже, как данные представлены в столбце

ТАБЛИЦА 1: COMMENTS_TABLE

  id   | comments
  1    | Manually added (BPM001). Currency code does not exists(TECH23).  
  2    | Invalid counterparty (EXC001). Manually added (BPM002)

ТАБЛИЦА 2: ERROR_CODES

  id    | error_code  | error_type  
  1     | BPM001      | MAN  
  2     | EXC001      | EXC         
  3     | EXC002      | EXC
  4     | BPM002      | MAN 

Я могу получить все коды ошибок, используя REGEX_SUBSTR, но не знаю, как проверить это с помощью другой таблицы и, в зависимости от типа, отображать только одну. Например, если тип - MAN, в предложении select должен быть возвращен только этот код ошибки.

0
mithz 14 Мар 2018 в 06:51

2 ответа

Лучший ответ

Предлагаю вам определить иерархию error_codes в функции FIRST для поиска наиболее подходящего.

SQL Fiddle

Запрос 1 :

 SELECT c.id,
         MAX (
            ERROR_CODE)
         KEEP (DENSE_RANK FIRST
               ORDER BY CASE ERROR_TYPE WHEN 'MAN' THEN 1 WHEN 'EXC' THEN 2 END)
            AS ERROR_CODE,
         MAX (
            ERROR_TYPE)
         KEEP (DENSE_RANK FIRST
               ORDER BY CASE ERROR_TYPE WHEN 'MAN' THEN 1 WHEN 'EXC' THEN 2 END)
            AS ERROR_TYPE
    FROM ERROR_CODES e
         JOIN COMMENTS_TABLE c ON c.COMMENTS LIKE '%' || e.ERROR_CODE || '%'
GROUP BY c.id

Результаты :

| ID | ERROR_CODE | ERROR_TYPE |
|----|------------|------------|
|  1 |     BPM001 |        MAN |
|  2 |     BPM002 |        MAN |

ИЗМЕНИТЬ : вы сказали в своих комментариях

Это полезно, но у меня есть несколько полей в предложении select, и добавление этого в группу может быть проблемой.

Один из вариантов может заключаться в использовании предложения WITH для определения этого набора результатов и последующего соединения с другими столбцами.

with res as
(
  select ...
         --query1
)
select t.other_columns, r.id, r.error_code ... 
   from other_table join res on ...

Вы также можете использовать row_number() в качестве альтернативы (что на самом деле было моим первоначальным ответом. Но я изменил его на KEEP .. DENSE_RANK, поскольку он эффективен.

SELECT * FROM
( SELECT c.id
    ,ERROR_CODE
    ,ERROR_TYPE
    --Other columns,
    ,row_number() OVER (
        PARTITION BY c.id ORDER BY CASE error_type
                WHEN 'MAN'
                    THEN 1
                WHEN 'EXC'
                    THEN 2
                ELSE 3
                END
        ) AS rn
FROM ERROR_CODES e
INNER JOIN COMMENTS_TABLE c 
ON c.COMMENTS LIKE '%' || e.ERROR_CODE || '%'
 ) WHERE rn = 1;

Скрипка

1
Kaushik Nayak 14 Мар 2018 в 16:01

Вы можете сортировать, расставлять приоритеты и фильтровать записи с помощью аналитических функций.

with comments as(
    select 1 as id
          ,'Manually added (BPM001). Currency code does not exists(TECH23).' as comments 
      from dual union all
    select 2 as id
          ,'Invalid counterparty (EXC001). Manually added (BPM002)'          as comments 
      from dual
)
,error_codes as(
    select 1 as id, 'BPM001' as error_code, 'MAN' as error_type from dual union all 
    select 2 as id, 'EXC001' as error_code, 'EXC' as error_type from dual union all        
    select 3 as id, 'EXC002' as error_code, 'EXC' as error_type from dual union all
    select 4 as id, 'BPM002' as error_code, 'MAN' as error_type from dual
)
-- Everything above this line is not part of the query. Just for generating test data
select * 
  from (select c.id as comment_id
              ,c.comments
              ,e.error_code
              ,row_number() over(
                partition by c.id                              -- For each comment
                    order by case error_type when 'MAN' then 1 -- First prio
                                             when 'EXC' then 2 -- Second prio
                                                        else 3 -- Everything else
                              end) as rn
           from comments    c
           join error_codes e on(
                e.error_code = regexp_substr(c.comments, e.error_code)
           )
        )
  where rn = 1 -- Pick the highest priority code
 /

Если бы вы могли добавить столбец приоритета в свой код ошибки (или даже error_type), вы могли бы пропустить логику case / when в порядке by и просто заменив его столбцом приоритета.

0
Ronnis 14 Мар 2018 в 15:21