在Oracle中使用SQL或PL/SQL更新第一个重复行的UPDATE语句

11

我正在寻找一条 UPDATE 语句,它将仅更新单个重复行并保留其余(重复行)不变,使用 ROWID 或其他元素来利用 Oracle SQL 或 PL/SQL?

这里是一个示例 duptest 表供使用:

CREATE TABLE duptest (ID VARCHAR2(5), NONID VARCHAR2(5));
  • 运行一次INSERT INTO duptest VALUES('1','a');

  • 运行四次INSERT INTO duptest VALUES('2','b');

同时,第一个重复的行必须始终更新(而不是删除),而其他三个(3)行必须保持不变!

非常感谢, Val。


1
你如何确定哪个2,b是第一个?如果没有可以排序的时间戳列...你是不是想说“一个”而不是“第一个”? - Mark Brady
包括测试表和示例插入使得回答你的问题更容易。不错。 - JosephStyons
5个回答

15

这个方案是否适合您:

update duptest 
set nonid = 'c'
WHERE ROWID IN (SELECT   MIN (ROWID)
                              FROM duptest 
                          GROUP BY id, nonid)

1
UPDATE  duptest 
SET     nonid = 'c' 
WHERE   nonid = 'b' 
    AND rowid = (SELECT min(rowid) 
                 FROM   duptest 
                 WHERE nonid = 'b');

1

这对我很有效,即使是重复运行也是如此。

--third, update the one row
UPDATE DUPTEST DT
SET DT.NONID = 'c'
WHERE (DT.ID,DT.ROWID) IN(
                         --second, find the row id of the first dup
                         SELECT 
                           DT.ID
                          ,MIN(DT.ROWID) AS FIRST_ROW_ID
                         FROM DUPTEST DT
                         WHERE ID IN(
                                    --first, find the dups
                                    SELECT ID
                                    FROM DUPTEST
                                    GROUP BY ID
                                    HAVING COUNT(*) > 1
                                    )
                         GROUP BY
                           DT.ID
                         )

1

我认为这应该可以工作。

UPDATE DUPTEST SET NONID = 'C'
WHERE ROWID in (
    Select ROWID from (
        SELECT ROWID, Row_Number() over (Partition By ID, NONID order by ID) rn
    ) WHERE rn = 1
)

0

我知道这并没有回答你最初的问题,但是你的表中没有键值,所以你遇到的问题就源自于此。

因此,我的建议是——如果特定的应用程序可以支持——请在你的表中添加一个键列(例如:REAL_ID,类型为INTEGER)。

然后,你就可以找到重复记录中最低的ID。

select min (real_id) 
from duptest
group by (id, nonid)

并仅更新这些行:

update duptest
set nonid = 'C'
where real_id in (<select from above>)

我相信更新语句可以进行一定的调整,但我希望它能够说明这个想法。

优点是设计更加“清晰”(您的id列实际上不是一个id),并且比依赖于特定于数据库的rowid版本更具可移植性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接