需要查找并列出多个CTE之间的重复项

时间:2019-03-27 18:18:27

标签: sql postgresql duplicates common-table-expression

我需要在用户未正确输入名称的单个表上标识重复项(例如,不是在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中进行操作。

1 个答案:

答案 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;

希望我能正确理解你的意图。

将字符串与=进行比较没有问题,这肯定是一种误解。