检查 table 相似的文本记录并删除重复记录(SQL Oracle 数据库。)

Check table for similar text records and remove duplicate records (SQL Oracle database. )

我需要检查 oracle 数据库 table 是否有相似的记录并获取不同的字符数。为此,我使用此查询:

CREATE TABLE match_tab (
  id   NUMBER,
  col1 VARCHAR2(15),
  CONSTRAINT match_tab_pk PRIMARY  KEY (id)
);

INSERT INTO match_tab VALUES (1, 'Peter Parker');
INSERT INTO match_tab VALUES (2, 'peter parker');
INSERT INTO match_tab VALUES (3, 'Clark Kent' );
INSERT INTO match_tab VALUES (4, 'Wonder Woman');
INSERT INTO match_tab VALUES (5, 'Superman');
INSERT INTO match_tab VALUES (6, 'The Hulk');
INSERT INTO match_tab VALUES (7, 'Ponder Woman');
INSERT INTO match_tab VALUES (8, 'Claire Kent' );
INSERT INTO match_tab VALUES (9, 'Superman');
INSERT INTO match_tab VALUES (10, 'Iron Man');
COMMIT;

select  m1.col1 as mc1, 
        m2.col1 as mc2,
        UTL_MATCH.edit_distance(m1.col1, m2.col1) as match
from match_tab m1
join match_tab m2 on (1 = 1)
where UTL_MATCH.edit_distance(m1.col1, m2.col1) = 2 and m1.id != m2.id; 

给出结果:

   MC1             MC2                  MATCH
--------------- --------------- ----------
Peter Parker    peter parker             2
peter parker    Peter Parker             2
Clark Kent      Claire Kent              2
Claire Kent     Clark Kent               2
  1. 如何删除重复的记录并得到这样的结果:

    MC1             MC2                  MATCH
    --------------- --------------- ----------
    Peter Parker    peter parker             2
    Clark Kent      Claire Kent              2
    
  2. 是否可以优化此查询?对于大量数据, 需要很长时间。


我将不胜感激任何帮助!

删除“重复项”很简单(例如使用 < 而不是 !=):

SQL> SELECT m1.col1 AS mc1,
  2         m2.col1 AS mc2,
  3         UTL_MATCH.edit_distance (m1.col1, m2.col1) AS match
  4    FROM match_tab m1
  5         JOIN match_tab m2
  6            ON     UTL_MATCH.edit_distance (m1.col1, m2.col1) = 2
  7               AND m1.id < m2.id;

MC1             MC2                  MATCH
--------------- --------------- ----------
Peter Parker    peter parker             2
Clark Kent      Claire Kent              2

SQL>

如何让它更快?我不知道你是否可以让它更快;您正在比较所有行,并且 - 对于大表 - 这需要时间。

我删除了你的 cross-join(使用 on 1 = 1),因为你实际上可以在 utl_match.edit_distance 上加入 m1m2,但我不希望这是对您的代码的重大改进。

您可以:

  • 使用分层查询,这样您就不需要阅读 table 两次,也不需要 self-join;
  • 添加过滤器以检查列的长度是否相似(这可能比使用 UTL_MATCH 更简单,如果优化器首先使用此过滤器,它可能能够排除很多比较) ;和
  • 过滤 PRIOR id < id 而不是使用 != 来比较 id 并消除重复项:
SELECT PRIOR col1 as mc1, 
       col1 as mc2,
       UTL_MATCH.edit_distance(PRIOR col1, col1) as match
FROM   match_tab
WHERE  LEVEL = 2
CONNECT BY
       LENGTH(PRIOR col1) - LENGTH(col1) BETWEEN -1 AND +1
AND    PRIOR id < id
AND    UTL_MATCH.edit_distance(PRIOR col1, col1) BETWEEN 1 AND 2;

对于您的示例数据,输出:

MC1 MC2 MATCH
Peter Parker peter parker 2
Clark Kent Claire Kent 2
Wonder Woman Ponder Woman 1

注意:如果您只想要 edit-distance 为 2 的匹配项,则将最后一行更改为 AND UTL_MATCH.edit_distance(PRIOR col1, col1) = 2;

db<>fiddle here