我需要在用户未正确输入名称的单个表上标识重复项(例如,不是在fname
中放入“ John”,而在lname
中放入“ Smith”,而是一条已经存在的记录) ,他们将{Smith“放在fname
中,将” John“放入lname
中)。我需要识别这些重复项,并列出重复项及其正确的记录副本。
我设置了两个CTE,一个仅拉出我需要的列,另一个拉出具有要删除的不良信息的相同列。主要查询提取所有列,并将完整表与CTE表进行比较,并将其与重复项进行比较。我无法在两个CTE之间进行比较,因为它会出错(由用作表达式的子查询返回的行多于一个)。查询以其当前形式返回9813408908970990872314结果(我放弃了导出650k)。这是PostgreSQL数据库,未知版本,但我相信它是9+。人员表上有约320k有效行,而wrong_order
CTE中有2499条有效行。关键字段是person.number
,但每个字段都有唯一的编号,即使输入错误也是如此(由于删除的记录与数据保留规则冲突,因此每一行都会得到一个,但并非所有行都有一个)。
WITH
correct_order AS (
SELECT (p.lname||', '|| p.fname) AS "name",
p.number AS "num",
p.birthdate AS "dob"
FROM person p
WHERE p.lname IS NOT NULL
),
wrong_order AS (
SELECT (p.fname||', '|| p.lname) AS "name",
p.number AS "num",
p.birthdate AS "dob"
FROM person p
WHERE (p.lname||', '|| p.fname) IN (p.fname||', '|| p.lname)
)
SELECT
correct_order.name AS "Correct Name",
correct_order.num AS "Correct Num",
correct_order.birthdate AS "Correct DOB",
wrong_order.name AS "Wrong Name",
wrong_order.num AS "Wrong Num",
wrong_order.birthdate AS "Wrong DOB"
FROM
correct_order, wrong_order
WHERE
correct_order.name IN (SELECT wrong_order.name FROM wrong_order)
我希望看到两个CTE的名称/编号/标识,其中两组数据在两者之间匹配。相反,我得到的是一个重复,其中这六个值的每种可能的组合。我尝试在主查询(correct_order JOIN wrong_order ON correct_order.name = wrong_order.name
)中使用联接,但是不能在字符串上使用=
,而使用IN
则抛出“多行...”。在我没有足够的力量而没有一些帮助的情况下,尽管有可能在powershell中进行操作。
答案 0 :(得分:1)
您那里有意外的交叉联接(FROM correct_order, wrong_order
没有联接条件)。这就解释了天文的行数。
您需要查询以下几行:
SELECTS /* columns you need */
FROM person AS correct
JOIN person AS wrong
ON (correct.fname, correct.lname) =
(wrong.lname, wrong.fname)
WHERE correct.lname IS NOT NULL;
希望我能正确理解你的意图。
将字符串与=
进行比较没有问题,这肯定是一种误解。