Sql 如何删除同一表中具有相同CLOB数据的重复行?

Sql 如何删除同一表中具有相同CLOB数据的重复行?,sql,oracle,oracle12c,Sql,Oracle,Oracle12c,我在Oracle中有一个表,其中一列(名为CONTENTSTRING)是CLOB。但是,此表中的某些行在此列中具有相同的数据。我想做的是删除所有的行,除了一个具有相同数据的行。我怎样才能做到这一点 通过谷歌搜索,我看到了大量比较两列的例子。我还看到两个不同表格之间的比较示例。我没有看到的是一个使用一个表并只比较行的示例!我确实认为我可能需要使用这个函数:dbms\u lob.compare。但是,我仍然不确定如何设置此函数 从程序员的角度来看,我认为也许我应该这样做: SELECT CONTEN

我在Oracle中有一个表,其中一列(名为
CONTENTSTRING
)是
CLOB
。但是,此表中的某些行在此列中具有相同的数据。我想做的是删除所有的行,除了一个具有相同数据的行。我怎样才能做到这一点

通过谷歌搜索,我看到了大量比较两列的例子。我还看到两个不同表格之间的比较示例。我没有看到的是一个使用一个表并只比较行的示例!我确实认为我可能需要使用这个函数:
dbms\u lob.compare
。但是,我仍然不确定如何设置此函数

从程序员的角度来看,我认为也许我应该这样做:

SELECT CONTENTSTRING FROM TABLE_ALPHA A
然后从与
table_ALPHA B
相同的表中进行另一次选择,然后使用
dmbs_lob.compare
比较这两列。如果行号不同且列内容相同,则可以删除
表_ALPHA B
中的行

我认为这是正确的方法,但是我应该如何在Oracle中使用SQL编写这篇文章呢?我将非常感谢在这方面的任何帮助或资源。谢谢

DELETE
FROM TABLE_ALPHA A
WHERE EXISTS (
  SELECT 1 FROM TABLE_ALPHA B
  WHERE DBMS_LOB.COMPARE(A.CONTENTSTRING, B.CONTENTSTRING) = 0
  AND A.ROWID > B.ROWID
)
这将删除除第一个副本之外的所有副本


这将删除除第一个副本以外的所有副本。

此答案假定源表中有一个主键字段(我称之为
id

您可以使用子查询列出重复记录的
id
s:这是通过将表与
dbms\u lob.compare
id
上的一个比较子句自联接来实现的。如果存在具有相同CLOB内容的重复行,则选择所有
id
s,但选择最古老的(即最小的)。外部查询只删除所选的
id
s。<代码> NVL<代码>将考虑<代码> null <代码>内容作为重复(如果与您的用例不相关,只删除它们)。< /P>
请参阅。

此答案假设源表中有一个主键字段(我称之为
id

您可以使用子查询列出重复记录的
id
s:这是通过将表与
dbms\u lob.compare
id
上的一个比较子句自联接来实现的。如果存在具有相同CLOB内容的重复行,则选择所有
id
s,但选择最古老的(即最小的)。外部查询只删除所选的
id
s。<代码> NVL<代码>将考虑<代码> null <代码>内容作为重复(如果与您的用例不相关,只删除它们)。< /P>
请参阅。

表中是否有主键?如果是,列名称是什么?如果您可以编辑您的答案以添加示例数据和预期结果,那就太好了。表中是否有主键?如果是,列名称是什么?如果您可以编辑您的答案来添加示例数据和预期结果,这将是很好的。这将考虑一个<代码> null <代码>值和一个字符串<代码>‘null’< /代码>是相同的;这不应该是真的。最好是使用
((a.contentString为NULL,b.contentString为NULL)或DBMS_LOB.compare(a.contentString,b.contentString)=0)比较
NULL
。@MT0:这是一个边缘情况,但你是对的,谢谢你指出这一点。我更新了查询(和小提琴)。谢谢你的帮助!我最终使用了Vladimir的解决方案,因为我最终需要使用row.id。谢谢你帮我调查此事!这将考虑一个<代码> null <代码>值和一个字符串<代码>“null”<代码>是相同的;这不应该是真的。最好是使用
((a.contentString为NULL,b.contentString为NULL)或DBMS_LOB.compare(a.contentString,b.contentString)=0)比较
NULL
。@MT0:这是一个边缘情况,但你是对的,谢谢你指出这一点。我更新了查询(和小提琴)。谢谢你的帮助!我最终使用了Vladimir的解决方案,因为我最终需要使用row.id。谢谢你帮我调查此事!非常感谢你!我能够使用这个查询来完成我所需要的!我在每个select语句中添加了一个条件,以限制要比较的行数,因为查询需要很长时间。非常感谢!我能够使用这个查询来完成我所需要的!我在每个select语句中添加了一个条件,以限制要比较的行数,因为查询需要很长时间。
DELETE FROM TABLE_ALPHA 
WHERE id IN (
    SELECT b.id
    FROM TABLE_ALPHA a
    INNER JOIN TABLE_ALPHA b 
        ON  
        (
            (a.contentString IS NULL AND b.contentString IS NULL) 
            OR dbms_lob.compare(a.CONTENTSTRING, b.CONTENTSTRING) = 0
        ) 
        AND b.id > a.id
);