当前表:
Users:
ID | name|Time |
001| John|Aug 15 |
001| Coga|March 1 |
002| Pat |May 10 |
我需要编写一个查询,找到具有相同ID的人并删除最旧的记录。
我能够找到最旧的记录,但如何在同一查询中删除它呢?
SELECT ID, MIN(Time)
FROM Users
WHERE ID in (SELECT ID FROM USERS group by ID having count(ID) > 1)
group by ID;
Result :
ID | Name | Time |
001| Coga | March 1|
删除时我需要删除具有特定ID和特定时间的确切(最旧)记录。
答案 0 :(得分:1)
您可以使用此查询:
delete
from users
where (id, time) in
(select id, time
from (select id, time,
row_number() over (partition by id order by time desc) as rn,
from users) sub
where rn > 1)
它将删除某个人的所有“重复”,但最新的除外。我们的想法是,当您对某个ID的出现次数进行编号时,从最近到旧,只应保留编号为1的记录。
ROWID
正如下面评论中提到的guigui42,Oracle specific pseudo-column rowid
可能会进一步提升绩效。如果您没有以id, time
字段开头的索引,那肯定会出现这种情况:
delete
from users
where rowid in
(select rowid
from (select rowid,
row_number() over (partition by id order by time desc) as rn,
from users) sub
where rn > 1)
答案 1 :(得分:0)
尝试使用Windows函数:
ROW_NUMBER
会帮助您在ID
之前找到第一个(如果ID
和TIME
有重复项,我们只选择其中一个)
COUNT(*) OVER (PARTITION BY)
将通过ID
DELETE USERS
WHERE EXISTS
(SELECT 1
FROM
(SELECT ID, TIME,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY TIME) AS RN,
COUNT(*) OVER (PARTITION BY ID) CN
FROM USERS) U
WHERE U.ID = USERS.ID
AND U.TIME = USERS.TIME
AND U.RN = 1 -- FIRST ONE WITH THAT ID
AND U.CN > 1 -- WE HAVE MORE THAN ONE
)
答案 2 :(得分:0)
delete
from
USERS
where
U_TIME in (select
U_TIME
from
(select
U_ID,min(U_TIME) as U_TIME,count(rownum) as CNT
from
USERS
group by
U_ID)
where
CNT>1 )
;
如果您有任何主键约束,请告诉我