模糊匹配 postgresql 中的重复项并将重复项移动到新的 table
Fuzzy matching duplicates in postgresql and move the duplicates to a new table
我有一个用户 table,它具有以下字段
id, first_name, last_name, street_address, city, state, zip-code, firm, user_identifier, created_at, update_at
。
这个 table 有很多重复项。
我想通过 first_name, last_name and street_address
模糊匹配它们。
这是我所做的
我创建了一个包含以下字段的新 table
CREATE TABLE dupes(
id bigint NOT NULL,
first_name TEXT,
last_name TEXT,
street_address CHAR(50),
searched_name TEXT,
searched_user_id bigint
);
接下来我有这个函数,它应该循环遍历字段并插入到新的 table (dupes
) 中,其中相似度高于 ```.75
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
$$;
不幸的是,我得到了返回的每一行的更多副本。
我对此很陌生。有人可以帮忙吗?
谢谢
这应该不需要过程编程。 (基于集合做它甚至可以让你避免太多的重复……;-))
首先:
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
请评论,如果这需要调整/进一步的细节。
我有一个用户 table,它具有以下字段
id, first_name, last_name, street_address, city, state, zip-code, firm, user_identifier, created_at, update_at
。
这个 table 有很多重复项。
我想通过 first_name, last_name and street_address
模糊匹配它们。
这是我所做的
我创建了一个包含以下字段的新 table
CREATE TABLE dupes(
id bigint NOT NULL,
first_name TEXT,
last_name TEXT,
street_address CHAR(50),
searched_name TEXT,
searched_user_id bigint
);
接下来我有这个函数,它应该循环遍历字段并插入到新的 table (dupes
) 中,其中相似度高于 ```.75
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
$$;
不幸的是,我得到了返回的每一行的更多副本。
我对此很陌生。有人可以帮忙吗?
谢谢
这应该不需要过程编程。 (基于集合做它甚至可以让你避免太多的重复……;-))
首先:
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
请评论,如果这需要调整/进一步的细节。