我在Oracle中有一张表,其中的一列(名为CONTENTSTRING
)是CLOB
。但是,此表中的某些行在此列中具有相同的数据。我想做的是除去所有具有相同数据的行。我该怎么做?
在谷歌搜索中,我看到了大量用于比较两列的示例。我还看到了两个不同表之间进行比较的示例。我看不到的是一个使用一个表并仅比较行的示例!我确实认为我可能需要使用以下功能:dbms_lob.compare
。但是,我仍然不确定如何设置此功能。
从程序员的角度来看,我认为也许我应该做些类似的事情:
SELECT CONTENTSTRING FROM TABLE_ALPHA A
,然后以某种方式从与TABLE_ALPHA B
相同的表中进行另一个选择,然后使用dmbs_lob.compare
比较两列。如果行号不同且列内容相等,则可以删除TABLE_ALPHA B
中的行。
我认为这是正确的方法,但是我将如何使用SQL在Oracle中准确地写出来呢?我将不胜感激。谢谢!
答案 0 :(得分:2)
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
)
这会删除除第一个副本外的所有副本。
答案 1 :(得分:1)
此答案假设您在源表中有一个主键字段(我称之为id
)。
您可以使用子查询来列出重复记录中的id
:通过将表与dbms_lob.compare
和id
上的比较子句进行自我连接,可以实现此目的。如果存在具有相同CLOB内容的重复行,则选择所有id
,但最古老(即最小)的{em>。外部查询仅删除所选的id
。 NVL
会将NULL
的内容视为重复内容(如果与您的用例无关,则将其删除)。
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
);
请参见this db fiddle。