Oracle:为什么我不能在 delete 子句中依赖 ROWNUM

Oracle: Why I cannot rely on ROWNUM in a delete clause

我有这样的说法:

SELECT MIN(ROWNUM) FROM my_table
GROUP BY NAME 
HAVING COUNT(NAME) > 1);

这条语句给了我第一个副本的 rownum,但是当把这条语句转换成 DELETE 时,它只是删除了所有内容。为什么会这样?

这是因为 ROWNUM 是一个伪列,这意味着它们在物理上不存在。你最好使用rowid来删除记录。

要删除重复项,您可以这样尝试:

DELETE FROM mytable a
WHERE EXISTS( SELECT 1 FROM mytable b
              WHERE a.id = b.id
              AND a.name = b.name
              AND a.rowid > b.rowid )

使用rownum删除重复记录意义不大。如果您需要删除重复行,只为 name 的每个值保留一行,请尝试以下操作:

DELETE FROM mytable
  WHERE ROWID IN (SELECT ID
                    FROM (SELECT ROWID ID, ROW_NUMBER() OVER 
                             (PARTITION BY name ORDER BY name) numRows FROM mytable
                         )
                   WHERE numRows > 1)

通过在 ORDER BY 子句中添加更多列,您可以选择删除包含 greatest/smallest ID 或其他字段的记录。