mysql - 为什么删除重复记录时出现 max(rowid) 或 min(rowid) ?

标签 mysql oracle rowid

我们可以在不使用伪列rowid的情况下删除重复记录吗... 删除重复记录时 max(rowid)/min(rowid) 的含义是什么?

最佳答案

ROWID 是 Oracle 用于定位物理记录的内部行标识符。因此,即使您的“ID”可能有重复的值,每个记录 ROWID 仍然是唯一的。

create table prices(
   id       varchar2(15) not null
  ,price    number       not null
  ,upd_date date         not null
--  ,primary key(id)
);

ROWID                ID PRICE UPD_DATE
------------------   -- ----- ----------
AChTgbADaAAFgxYAAA   A  7     2018-04-10

AChTgbADaAAFgxYAAB   B  8     2018-04-09
AChTgbADaAAFgxYAAC   B  8     2018-04-09
AChTgbADaAAFgxYAAD   B  8     2018-04-09

AChTgbADaAAFgxYAAE   C  9     2018-04-06
AChTgbADaAAFgxYAAF   C  8     2018-04-05
AChTgbADaAAFgxYAAG   C  7     2018-04-04

组中的 MAX(rowid)通常是最近插入的记录,但这种假设在生产代码中经常是错误的。只能依靠它来删除完美的重复。完美的重复是 select unique * 产生一条记录的重复。对于所有其他用途,您需要一个鉴别器。鉴别器列可用于区分两个记录,例如使用指示修改时间的更新日期。

如果您使用典型的 ROWID 方法对我的示例表进行重复数据删除,您将错误地删除最新价格 9(如 upd_date 所证明的)。

delete
  from prices
 where rowid not in(
        select max(rowid)
          from prices
      group by id);

更好的方法是首先使用鉴别器,然后作为最后的手段使用 ROWID。

delete 
  from prices
 where rowid in(
        select rid
          from (select rowid as rid
                      ,row_number() over(            -- Assign a sequence number
                          partition by id            -- Group rows by ID
                              order by upd_date desc -- Sort them by upd_date first  
                                      ,rowid desc    -- Then by ROWID
                      ) as rn
                   from prices
               )
     -- The most recent record will be rn = 1.
     -- The second most recent record will be rn = 2, etcetera
        where rn > 1 -- Select only the duplicates ("after" the most recent one record
       );

关于mysql - 为什么删除重复记录时出现 max(rowid) 或 min(rowid) ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50055154/

相关文章:

mysql - 为什么这个 MySQL CASE 查询不起作用?

sql - Oracle SQL : Is it possible using SUBSTR and INSTR to return ALL Strings in a given text field?

sql - plsql - 获取第一行 - 哪个更好?

java - java中oracle sql的问题

oracle - 为什么我们不能使用 ROWID 作为主键?

php - SQL - 连接两个表

MySql 根据员工 'expense' 组中的值对 'expense type' 表中的不同类型的费用求和

Sqlite:插入触发器中对两个表的更新是原子的吗?

sql - 插入记录并保留主键值

php - 如何仅存储月份和年份并将所有日期的日期默认设置为 1?