You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用CTE删除数据表中的重复行?解决ORA-00928缺失SELECT关键字错误

Fixing ORA-00928 When Deleting Duplicates with CTE & ROW_NUMBER()

Hey there! Let's break down why you're hitting that ORA-00928: missing SELECT keyword error and fix it so you can delete those duplicate rows smoothly.

The Root Cause

Your original CTE works perfectly for spotting duplicates, but Oracle doesn’t let you just swap out the SELECT statement with DELETE directly. The syntax for using a CTE with DELETE needs to explicitly target your base table and reference the CTE to filter which rows to remove—you can’t just replace the final SELECT with DELETE.

Correct Delete Query Using CTE

First, let’s confirm your CTE correctly flags duplicates (you already have this part right!). To turn it into a delete operation, wrap the CTE and then use DELETE with a subquery to target rows where rn > 1 (these are your duplicate entries):

WITH RowNumCTE AS (
    SELECT ID,
           parcelid,
           propertyaddress,
           saledate,
           saleprice,
           legalreference,
           ROW_NUMBER() OVER (
               PARTITION BY parcelid, propertyaddress, saledate, saleprice, legalreference 
               ORDER BY id
           ) AS rn
    FROM housedata
)
DELETE FROM housedata
WHERE ID IN (SELECT ID FROM RowNumCTE WHERE rn > 1);

Alternative: Inline Subquery (No CTE)

If you prefer a more compact approach, you can nest the row-number logic directly in the delete statement without a CTE:

DELETE FROM housedata
WHERE ID IN (
    SELECT ID
    FROM (
        SELECT ID,
               ROW_NUMBER() OVER (
                   PARTITION BY parcelid, propertyaddress, saledate, saleprice, legalreference 
                   ORDER BY id
               ) AS rn
        FROM housedata
    )
    WHERE rn > 1
);

Pro Tip Before Deleting!

Always run a SELECT first to verify you’re targeting the right rows. Use your original CTE with a filter for rn > 1 to double-check which duplicates will be removed:

WITH RowNumCTE AS (
    SELECT ID,parcelid,propertyaddress,saledate,saleprice,legalreference,
           ROW_NUMBER() OVER (PARTITION BY parcelid,propertyaddress,saledate,saleprice,legalreference ORDER BY id) AS rn
    FROM housedata
)
SELECT * FROM RowNumCTE WHERE rn > 1;

This way you won’t accidentally delete rows you want to keep!

内容的提问来源于stack exchange,提问作者Mohammad Liton Hossain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 17:42:33