如何在Oracle中删除重复行

3

我需要帮助删除重复行。我使用以下方法从一个表格中删除了重复行:

DELETE FROM names a
WHERE ROWID > (SELECT MIN(ROWID) FROM names b
WHERE b.name=a.name
AND b.age=a.age
);

虽然在这张特定的表格上可以工作,但我在另一张表格上做了同样的事情,该表格每个医生都有重复的参考编号,但有不同的唯一代码。

doc_name  ref_no  unique_code
------------------------------
abcd      1010     1111
abcd      1010     1112
cdef      1011     1113
cdef      1011     1114

My result should look like this:

doc_name ref_no unique_code
---------------------------
abcd     1010      1111
cdef     1011      1113

1
你用了什么查询语句来进行第二个查询? - Moudiz
4个回答

4
您可以使用ROW_NUMBER()来检测重复行并删除它们。
DELETE tblName
WHERE ROWID IN (
    SELECT ROWID
    FROM(
      SELECT ROW_NUMBER() OVER (PARTITION BY doc_name, ref_no ORDER BY doc_name, ref_no) AS Rn
            ,doc_name
            ,ref_no
            ,unique_code
      FROM tblName
    )
    WHERE Rn > 1
   )

在Oracle中,您无法从公共表达式(CTE)中进行删除操作。 - user330315
@sqluser,我尝试了你的查询语句,但是出现了以下错误: `WITH C AS( SELECT ROW_NUMBER() OVER (PARTITION BY doc_name, ref_no ORDER BY doc_name, ref_no) AS Rn , doc_name , ref_no , unq_cd FROM doc_unique ) DELETE FROM C WHERE Rn > 1` SQL> / DELETE FROM C WHERE Rn > 1 * ERROR at line 8: ORA-00928: missing SELECT keyword - Iftekhar
@Iftekhar,正如@a_horse_with_no_name在他的评论中提到的,我们不能从CTE中删除。所以我修改了查询。请查看更新内容。感谢@a_horse_with_no_name指出这一点。 - sqluser
@sqluser,感谢您更新查询语句。由于我要删除的重复行所在的表中没有ref_no,因此我稍微修改了新的查询语句。这个新的查询语句能够正常工作吗?或者我还需要包括父亲姓名(ft_nm)和母亲姓名(mt_nm)吗?DELETE t_doc_unique WHERE ROWID IN ( SELECT ROWID FROM( SELECT ROW_NUMBER() OVER (PARTITION BY doc_name,unq_cd ORDER BY doc_name, unq_cd) AS Rn ,doc_name ,unq_cd FROM t_doc_unique ) WHERE Rn > 1 ) / - Iftekhar

2
你是这样尝试的吗?
DELETE FROM names a
WHERE ROWID > (SELECT MIN(ROWID) FROM names b
WHERE b.doc_name=a.doc_name
AND b.ref_no=a.ref_no
)

尝试这个也行。
SELECT *
  FROM doc_unique
 WHERE (DIV_CD, DOC_NAME, B_DT, FT_NM, UNQ_CD, DESG_CD,
 SPEC_CD) IN (SELECT DIV_CD, DOC_NAME, B_DT, FT_NM, UNQ_CD, DESG_CD,
 SPEC_CD
                             FROM doc_unique
                            GROUP BY DIV_CD, DOC_NAME, B_DT, FT_NM, UNQ_CD, DESG_CD,
 SPEC_CD HAVING COUNT(*) > 1)

Moudiz,我已经手动搜索了数据表,并检查了重复值,但没有发现任何问题。您能告诉我检查重复行的正确方式吗?select DIV_CD,DOC_NAME,B_DT,FT_NM,UNQ_CD, DESG_CD,SPEC_CD,count(*) from doc_unique group by DIV_CD,DOC_NAME,B_DT,FT_NM, UNQ_CD,DESG_CD,SPEC_CD having count(unq_cd)>1 - Iftekhar
@Iftekhar 是的,看起来不错。但是请检查一下这个查询,这是另一种检查重复的方法。 - Moudiz
1
你的查询以检查重复项已经生效。非常感谢。 - Iftekhar

1
请尝试使用exists
delete from names a
where exists (
  select * 
  from names b
  where b.name = a.name
        and b.age = a.age
        and a.unique_code > b.unique_code 
)

0

您可以使用以下 SQL 查询删除重复数据:

delete from [table_name] where rowid in ( select max(rowid) from [table_name] group by [column_name] );

注意:[table_name] 类似于 STUDENT,[column_name] 类似于 STUD_ID。

查看截图


避免分享截图,链接可能会随着时间而失效。 - atish.s
谢谢你的分享,从现在开始我会注意的。@atish.s - Pradeep Wagh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接