首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Oracle ROWID 去重 SQL 解析:子查詢關聯邏輯詳解

     編輯:程式設計疑難解答

SQL 語句


SELECT * FROM XUTEST X 
WHERE ROWID != (
    SELECT MAX(ROWID) FROM XUTEST Y 
    WHERE Y.SUPID = X.SUPID
)

ROWID 特性

  • 每行唯一物理地址標識,不可變(除非行移動)。
  • 可用於精確定位、刪除重複行。

邏輯逐步拆解

假設表 XUTEST 數據:

ROWIDSUPID其他列
r11...
r22...
r32...
r42...
r53...

子查詢執行過程(相關子查詢)

對外層每行 X,子查詢計算:MAX(ROWID) WHERE SUPID = X.SUPID

  • X=r1 (SUPID=1) → 子查詢結果 MAX(r1) = r1 → ROWID != r1 為假 → 保留
  • X=r2 (SUPID=2) → 子查詢結果 MAX(r2,r3,r4) = r4 → ROWID != r4 為真 → 輸出 r2
  • X=r3 (SUPID=2) → 子查詢結果 r4 → ROWID != r4 為真 → 輸出 r3
  • X=r4 (SUPID=2) → 子查詢結果 r4 → ROWID != r4 為假 → 保留
  • X=r5 (SUPID=3) → 子查詢結果 r5 → ROWID != r5 為假 → 保留

結果

輸出 r2, r3 —— 即 SUPID=2 組中除最大 ROWID 外的所有行。
效果:按 SUPID 分組,保留 ROWID 最大(最新)的一行,刪除其餘重複行。

等價現代寫法(Oracle 12c+)


DELETE FROM XUTEST
WHERE ROWID NOT IN (
    SELECT MAX(ROWID) FROM XUTEST GROUP BY SUPID
);
-- 或使用 ROW_NUMBER()
DELETE FROM XUTEST
WHERE ROWID IN (
    SELECT ROWID FROM (
        SELECT ROWID, ROW_NUMBER() OVER (PARTITION BY SUPID ORDER BY ROWID DESC) rn
        FROM XUTEST
    ) WHERE rn > 1
);

注意事項

  • 子查詢返回單值,若分組無數據(理論不會)會報錯。
  • ROWID 大小反映插入順序(近似),MAX(ROWID) 通常對應最新插入行。
  • 大表建議使用分析函數 ROW_NUMBER(),性能更優、語義更清晰。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved