Sql Oracle检查另一个表中是否存在多个字符串中的任何一个

Sql Oracle检查另一个表中是否存在多个字符串中的任何一个,sql,oracle,Sql,Oracle,我是甲骨文的新手。我有一个需求,我需要从comment字段中获取所有错误代码,然后在另一个表中检查它以查看代码类型。根据代码的类型,我必须优先选择特定的类型,然后显示错误代码并将其与其他列一起输入csv。下面是数据在列中的显示方式 表1:意见表 id | comments 1 | Manually added (BPM001). Currency code does not exists(TECH23). 2 | Invalid counterparty (EXC

我是甲骨文的新手。我有一个需求,我需要从comment字段中获取所有错误代码,然后在另一个表中检查它以查看代码类型。根据代码的类型,我必须优先选择特定的类型,然后显示错误代码并将其与其他列一起输入csv。下面是数据在列中的显示方式

表1:意见表

  id   | comments
  1    | Manually added (BPM001). Currency code does not exists(TECH23).  
  2    | Invalid counterparty (EXC001). Manually added (BPM002)
表2:错误代码

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

我可以使用
REGEX\u SUBSTR
获取所有错误代码,但不确定如何与其他表一起检查,并且根据类型仅显示一个。例如,如果类型为MAN only,则应在select子句中返回错误代码。

我建议您定义一个
错误代码的层次结构
在
第一个
功能中搜索最佳匹配

查询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 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子句和adding中有多个字段 这可能是一个问题

一种选择是使用
WITH
子句定义此结果集,然后与其他列联接

with res as
(
  select ...
         --query1
)
select t.other_columns, r.id, r.error_code ... 
   from other_table join res on ...
你也可以选择使用
row\u number()
(这实际上是我最初的答案。但我把它改为
KEEP..densite\u 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

 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 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子句和adding中有多个字段 这可能是一个问题

一种选择是使用
WITH
子句定义此结果集,然后与其他列联接

with res as
(
  select ...
         --query1
)
select t.other_columns, r.id, r.error_code ... 
   from other_table join res on ...
你也可以选择使用
row\u number()
(这实际上是我最初的答案。但我把它改为
KEEP..densite\u 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;

您可以使用分析功能对记录进行排序、排序和筛选

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
 /

如果可以在错误代码(甚至错误类型)中添加优先级列,则可以跳过顺序中的case/when逻辑,只需将其替换为优先级列即可。

您可以使用分析函数对记录进行排序、排序和筛选

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
 /

如果可以在错误代码(甚至错误类型)中添加优先级列您可以跳过顺序中的case/when逻辑,只需将其替换为priority列即可。

您是否只对MAN error\u类型感兴趣?请清楚地显示预期的输出以及您尝试过的查询。当您说其他表时,是否意味着
error\u code
表?@事实:如果不是,则首选MAN error\u类型那就是EXC错误类型代码。@KaushikNayak:Yes other table表示错误代码表,其中包含所有可用的错误代码和类型。我将在某个时候更新查询,因为它在vpn中,我无法从那里获取。查询和预期输出。更新两者是否仅对人为错误类型感兴趣?请清楚地显示预期输出和类型还有您尝试过的查询。当您说“其他表”时,它是否表示“错误代码”
table?@Fact:首先优先选择“人工错误类型”,如果不是,则选择“EXC错误类型代码”。@KaushikNayak:是的,“其他表”表示“错误代码”表,其中包含所有可用的错误代码和类型。我将在vp中更新查询n我不能从那里接受它。查询和预期的输出。更新两者这是有帮助的,但我在select子句中有多个字段,在group by中添加这些字段可能是个问题。@mithila:请检查我添加了另一个解决方案。实际上,我的原始答案使用了
行号()
而不是
KEEP..densite\u RANK
。无论如何,你可以使用任何适合你的选项。这就是为什么我们总是坚持你发布预期的o/p bcoz,否则我们最终会做出假设。谢谢@Kaushik,这很有帮助。这很有帮助,但我在select子句中有多个字段,在group by中添加这些字段可能是个问题。@mithila:请检查我添加了另一个解决方案。事实上,我的原始答案使用了
行数()
而不是
保持..DENSE\u RANK
。无论如何,您可以使用任何适合您的选项。这就是为什么我们始终坚持您发布预期的o/p bcoz,否则我们最终会做出假设。感谢@Kaushik这一帮助。