我是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 :(得分:1)
我建议您定义error_codes
的层次结构
在FIRST
函数内搜索最佳匹配。
查询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
<强> Results 强>:
| ID | ERROR_CODE | ERROR_TYPE |
|----|------------|------------|
| 1 | BPM001 | MAN |
| 2 | BPM002 | MAN |
编辑:您在评论中说过
这是helpul,但我在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 :(得分:0)
您可以使用分析函数对记录进行排序,确定优先级并对其进行过滤。
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)添加一个优先级列,你可以跳过大小写/当顺序中的逻辑时,只需用优先级列替换它。