首页 > 解决方案 > 在 PostgreSQL 11.0 中递归比较多列中的子字符串

问题描述

我在 PostgreSQL 11.0 中有下表

code1                               code2                               code3                               code4
A (alimentary tract and metabolism) A01 (stomatological preparations)   A01A (stomatological preparations)  A01AA (caries prophylactic agents)
A (alimentary tract and metabolism) A01 (stomatological preparations)   A01A (stomatological preparations)  A01WB (herbal stomatological remedies containing mucilage)
A (alimentary tract and metabolism) A01 (stomatological preparations)   A01W (preparations)                 A01WB (herbal stomatological)

我想检查code1中的子字符串是否存在于col2中,code2中的子字符串是否存在于col3中,code3中的子字符串是否存在于col4中。是的,然后保留其他排除行。 例如:第 2 行:

我想检查A(在code1中)是否存在于code2中(A01:成立),A01(在code2中)是否存在于code3中(A01A:成立)和A01A(在code3中)是否存在于code4中(A01WB:持有错误)

所需的输出是:

code1                               code2                               code3                               code4
A (alimentary tract and metabolism) A01 (stomatological preparations)   A01A (stomatological preparations)  A01AA (caries prophylactic agents)
A (alimentary tract and metabolism) A01 (stomatological preparations)   A01W (preparations)                 A01WB (herbal stomatological)

伪代码类似于:

select * from tbl
where
 code1 ILIKE '%code2%' and 
code2 ILIKE '%code3%' and
code3 ILIKE '%code4%'

非常感谢这里的任何建议。

谢谢

标签: postgresqlsubstring

解决方案


您的示例数据显示了“代码(额外文本)”的一致格式。此外,code1、code2、code3、code4 的代码长度始终分别为 1、3、4、5。是不是总是这样。如果是这样,那么“为您工作”就是正确答案。但是,它确实取决于这些长度。另一种可能性是代码从第一个位置开始并以第一个空格结束。如果这成立,那么您可以使用正则表达式来提取代码部分,然后使用长度来比较提取的值:

with exp(re) as 
   ( values ('^[^ ]+'))  
select code1, code2, code3, code4 
  from ( select t.*
              , substring(code1, re) c1
              , substring(code2, re) c2
              , substring(code3, re) c3
              , substring(code4, re) c4             
           from tbl t cross join exp
       ) s 
where substr(c2,1,length(c1)) = c1
  and substr(c3,1,length(c2)) = c2 
  and substr(c4,1,length(c3)) = c3; 

它的优点是它不依赖于硬编码值。查看完整示例


推荐阅读