【问题标题】:Fuzzy matching duplicates in postgresql and move the duplicates to a new table在 postgresql 中模糊匹配重复项并将重复项移动到新表
【发布时间】:2019-12-23 21:23:11
【问题描述】:

我有一个用户表,其中包含以下字段 id, first_name, last_name, street_address, city, state, zip-code, firm, user_identifier, created_at, update_at。 这张表有很多重复。

我想通过first_name, last_name and street_address 模糊匹配它们。

这是我所做的

我创建了一个包含以下字段的新表

CREATE TABLE dupes(
   id  bigint NOT NULL,
   first_name    TEXT,
   last_name      TEXT,
   street_address        CHAR(50),
   searched_name TEXT,
   searched_user_id bigint
);

接下来我有这个函数,它应该遍历字段并插入到相似度高于 ```.75

的新表 (dupes)
DO 
$$
DECLARE 
    rec record;
    full_name varchar;
BEGIN
    FOR rec IN 
    SELECT id, first_name ||' '||last_name ||' '||street_address full_name 
    FROM users

    LOOP
        INSERT INTO dupes(id,first_name,last_name, street_address,searched_name, searched_user_id)
        SELECT id,first_name,last_name, street_address,rec.full_name,rec.id 
        FROM users
        WHERE similarity(first_name ||' '||last_name||' '||street_address, rec.full_name) > .75
        and  id<>rec.id;
    END LOOP;
END
$$;

不幸的是,每行返回的副本都越来越多。

我对此很陌生。有人可以帮忙吗?

谢谢

【问题讨论】:

    标签: sql postgresql similarity


    【解决方案1】:

    这不需要过程编程。 (基于设置甚至可以使您免于过多重复的重复... ;-))

    首先:

    WITH
    Matching (id, first_name, last_name, street_address, searched_name, searched_user_id) AS (
      SELECT DISTINCT
        l.id
        , l.first_name
        , l.last_name
        , l.street_address
        , r.first_name || ' ' || r.last_name
        , r.id
      FROM Users l
      JOIN Users r
        ON SIMILARITY(l.first_name || ' ' || l.last_name || ' ' || l.street_address,
                      r.first_name || ' ' || r.last_name || ' ' || r.street_address) > .50
           AND l.id < r.id
    )
    -- SELECT * FROM Matching
    INSERT INTO Dupes (id, first_name, last_name, street_address, searched_name, searched_user_id)
      (SELECT id, first_name, last_name, street_address, searched_name, searched_user_id FROM Matching)
    ;
    

    (为了说明三个记录之间的匹配没有过多的字母推送,已经调整了阈值......)

    查看实际操作:SQL Fiddle

    如果需要调整/进一步详细信息,请发表评论。

    【讨论】:

    • 这有帮助。非常感谢。我只需要使id UNIQUE,在插入时添加ON CONFLICT (id) DO NOTHING,这样我就不会重复了。
    • @MarianaLungu:请确保这对您的真实数据有预期的影响/确实有助于您随后的流程。 (DISTINCT 确实已经防止了记录级别的重复 - 但不是仅考虑 id。 - 因此,返回的集合对于 idsearched_user_id. - 只想到 传递闭包minimal set...)
    猜你喜欢
    • 2014-07-14
    • 2023-04-03
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    • 2016-06-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-27
    相关资源
    最近更新 更多