【问题标题】:Identifying duplicates in a table and kicking duplicate records to a another table识别表中的重复项并将重复记录踢到另一个表中
【发布时间】:2019-05-27 12:48:47
【问题描述】:

我的表中有一些员工记录,我们根据一个名为 workno 的字段来识别其中的重复记录。我在TABLE_A 中的数据如下所示

NAME  WORKNO       DATE
---------------------------
John     30000  09-JAN-2012
Franklin 40000  08-DEC-2014
Alicia   25000  19-JUL-2013
Jennifer 43000  20-JUL-2015
Gary     38000  15-SEP-2016
Joyce    25000  31-JAN-2017
Ahmad    25000  29-MAR-2017
James    55000  10-APR-2017
Jill     43000  12-OCT-2017
Jack     55000  18-JAN-2018

想象一下这里有将近一百万条记录。所以需要效率方面的帮助

我需要的输出:-

场景1:将不重复的记录(基于workno)保存在table_A本身中。上表中只有 John、Franklin 和 Gary 应该在最后,因为他们没有与 workno 重复的内容。

场景 2:特定 workno 的第一条记录(如果有重复)应写入 table_B。 workno 25000 的“Alicia”将被踢入 Table_B

场景 3:将第一个副本写入 table_B 后,应将剩余记录插入 table_C。带有 workno 的“Joyce”和“Ahmad”将被踢进 table_C

我已尝试编写适用于场景 1 和 2 的查询。如果有更好的方法,需要帮助。但是插入部分给我带来了错误(虽然查询部分工作正常)。

错误报告:

SQL 错误:ORA-01847:一个月中的某天必须介于 1 和该月的最后一天之间 01847. 00000 - “日期必须介于 1 和最后一天之间” *原因:
*行动:

Insert into ztempo
Select *
from (SELECT fname, minit, lname, bdate, address, sex, salary, superssn, dno, 
             ROW_NUMBER() OVER (PARTITION BY salary ORDER BY rownum) num
      from  Select *
            from ztemp 
            where salary in (Select salary from ztemp group by salary having Count(*) > 1)

           )

     )
where num = 1;

我想我可以在场景 3 的“where num > 1”末尾使用相同的代码进行一些调整。但是插入时有问题。请帮忙

需要帮助来完成它。提前致谢。

【问题讨论】:

  • 我的猜测是ztempo 中的列的定义顺序与子查询中的列不同。尝试明确指定列列表。
  • 您研究过触发器吗?这样你就可以在插入时修复它并且永远不会重复。从场景 2 到 3:在 table_a 上放置一个触发器后,在 table_b 上放置第二个触发器来解决您的问题。所有这些在一个查询中变得复杂,并且您必须经常运行以保持数据库“没有”重复。
  • 你好,Punnerud!我知道这很容易。但这些是日志表,数据不稳定,无法捕捉到触发器的问题。此外,随着创纪录的接近一百万,这些可能会在不同时间占用资源。我说的对吗?
  • 嗨威廉!是的,错误现在已纠正。如果可以,请帮助我提高效率。谢谢

标签: sql oracle sql-insert


【解决方案1】:

您收到的错误表明 ztempo 中的列与 ztemp 的顺序不同,或者日期列是 varchar2 并且包含无效日期,例如“2019-FEB-30”。

最好像这样显式声明您的列,以防表具有相同的列,但顺序不同:

insert into ztempo ( fname, minit, ... )

您在子查询中按薪水分组,这真的是您想要做的吗?而且我认为order by rownum 子句几乎没有任何作用。

【讨论】:

  • 你好艾尔森!该查询没有使用该数据的实际数据/或逻辑。只是在玩我自己的简单数据。我知道这没有意义:P。是的,格式有些问题,现在错误已清除。我使用 rownum 的顺序来不干扰重复记录在表中可用的顺序,因为与其他记录不同,第一个记录被踢到不同的表中。现在看起来合法吗?请澄清
【解决方案2】:

--场景1:插入其他表后从源表中删除重复项

Delete from table_a where workno in ( Select workno from table_a group by workno having count(*) > 1);

--场景 2:插入第一个副本

Insert into table_b Select fname, Workno, ord_date
from
(
     SELECT fname, workno, ord_date, 
     ROW_NUMBER() OVER (PARTITION BY workno ORDER BY rownum) num from
     (
     Select * from table_a 
     where workno in (
                      Select workno from table_a group by workno having count(*) > 1
                      )
      )
)
     where num = 1;

--场景 3:插入其他重复行

Insert into table_c Select fname, Workno, ord_date
from
(
      SELECT fname, workno, ord_date, 
      ROW_NUMBER() OVER (PARTITION BY workno ORDER BY rownum) num from
      (
      Select * from table_a 
      where workno in (
                       Select workno from table_a group by workno having count(*) > 1
                       )
       )
)
      where num > 1;

这是查看一百万条记录的有效方法吗?让我知道是否有其他解决方案。谢谢!

【讨论】:

  • 如果你已经成功了,判断效率的唯一方法是执行计划。有太多可能的变量,否则,尤其是你有什么索引。另外,运行需要多长时间。 “足够好”的速度取决于您的要求。
猜你喜欢
  • 1970-01-01
  • 2020-12-05
  • 2011-11-16
  • 2012-03-23
  • 2020-11-10
  • 2017-11-02
  • 1970-01-01
  • 2013-04-22
  • 1970-01-01
相关资源
最近更新 更多