检查另一个字符串中是否存在字符串变体

时间:2014-11-21 22:16:54

标签: sql regex oracle

我需要检查部分名称是否与全名匹配。例如:

Partial_Name   |  Full_Name
--------------------------------------
John,Smith     |  Smith William John
Eglid,Timothy  |  Timothy M Eglid

我不知道如何处理这种类型的匹配。

另一件事是名字和姓氏可能出现错误的顺序,使其变得更难。

我可以做这样的事情,但只有在名称相同且100%匹配

的情况下才有效

decode(LOWER(REGEXP_REPLACE(Partial_Name,'[^a-zA-Z'']','')), LOWER(REGEXP_REPLACE(Full_Name,'[^a-zA-Z'']','')), 'Same', 'Different')

3 个答案:

答案 0 :(得分:2)

您可以在提供的文本上使用此模式 - 适用于大多数引擎

([^ ,]+),([^ ,]+)(?=.*\b\1\b)(?=.*\b\2\b)  

Demo

答案 1 :(得分:1)

WITH 
/*
tab AS
(
SELECT 'Smith William John' Full_Name, 'John,Smith' Partial_Name FROM dual
UNION ALL SELECT 'Timothy M Eglid', 'Eglid,timothy' FROM dual
UNION ALL SELECT 'Tim M Egli', 'Egli,Tim,M2' FROM dual
UNION ALL SELECT 'Timot M Eg', 'Eg' FROM dual
),
*/
tmp AS (
  SELECT Full_Name, Partial_Name,
         trim(CASE WHEN instr(Partial_Name, ',') = 0 THEN Partial_Name         
                   ELSE regexp_substr(Partial_Name, '[^,]+', 1, lvl+1)
              END) token
  FROM tab t CROSS JOIN (SELECT lvl FROM (SELECT LEVEL-1 lvl FROM dual 
                         CONNECT BY LEVEL <= (SELECT MAX(LENGTH(Partial_Name) - LENGTH(REPLACE(Partial_Name, ',')))+1 FROM tab)))
  WHERE LENGTH(Partial_Name) - LENGTH(REPLACE(Partial_Name, ',')) >= lvl
) 
SELECT Full_Name, Partial_Name
FROM tmp
GROUP BY Full_Name, Partial_Name
HAVING count(DISTINCT token) 
       = count(DISTINCT CASE WHEN REGEXP_LIKE(Full_Name, token, 'i') 
                             THEN token ELSE NULL END);                             

tmp中,每个partial_name都会在令牌上分割(以逗号分隔)

生成的查询仅检索full_name匹配所有相应标记的行。

此查询使用partial_name中动态的逗号数。如果只有零个或一个逗号,则查询将更容易:

SELECT * FROM tab 
WHERE instr(Partial_Name, ',') > 0 
         AND REGEXP_LIKE(full_name, substr(Partial_Name, 1, instr(Partial_Name, ',')-1), 'ix')
         AND REGEXP_LIKE(full_name, substr(Partial_Name,instr(Partial_Name, ',')+1), 'ix')
      OR instr(Partial_Name, ',') = 0 
         AND REGEXP_LIKE(full_name, Partial_Name, 'ix');

答案 2 :(得分:0)

这就是我最终做的......不确定这是否是最佳方法。 我用逗号分割部分内容,并检查姓名和全名是否以全名出现。如果两者都存在则匹配。

CASE 
    WHEN 
     instr(trim(lower(Full_Name)), 
     trim(lower(REGEXP_SUBSTR(Partial_Name, '[^,]+', 1, 1)))) > 0
       AND 
     instr(trim(lower(Full_Name)), 
     trim(lower(REGEXP_SUBSTR(Partial_Name, '[^,]+', 1, 2)))) > 0
    THEN 'Y'
    ELSE 'N'
END AS MATCHING_NAMES