2008-10-28 17 views
11

Tek bir çoğaltma satırını yalnızca güncelleştirecek ve kalanları (yinelenen satırlar) olduğu gibi olduğu gibi kullanarak bir UPDATE ifadesi arıyorum ROWID veya Oracle SQL veya PL/SQL'de kullanmak için başka bir şey veya başka bir unsur? Ayrıca INSERT INTO duptest VALUES('2','b');İlk kopya satırını güncelleştirmek için SQL veya PL/SQL kullanarak Oracle'da UPDATE deyimi YALNIZCA

CREATE TABLE duptest (ID VARCHAR2(5), NONID VARCHAR2(5)); 
  • vadede bir INSERT INTO duptest VALUES('1','a');

  • çalıştırma dört (4) kat, birinci: Burada

    bir örnek duptest tablo ile çalışmak yinelenen satırın her zaman güncellenmesi gerekir (silinmez). er üç (3) olduğu gibi kalmak zorunda!

    Çok teşekkürler, Val.

+1

Hangi 2, b'nin ilk olduğunu nasıl belirlersiniz. Sipariş verebileceğiniz bir zaman damgası sütunu olmadan ... "İlk" yerine "bir" demek mi demek istediniz? –

+0

Test tablosu ve örnek ekler dahil, sorunuzu yanıtlamayı daha kolay hale getirdiniz. Güzel. – JosephStyons

cevap

15

Will sizin için bu işi:

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

Bu bile tekrarlanan ishal için, benim için çalıştı.

--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

Bunun işe yarayacağını düşünüyorum.

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

Bunun ilk sorunuza cevap vermez biliyorum ama senin masa ve sorunun bu belirli bir satır sonuçları hitap gelmiş üzerinde hiçbir anahtar yoktur.

Benim önerim - eğer belirli bir uygulama buna izin veriyorsa - tablonuza bir anahtar sütun eklemek (örneğin, INTEGER olarak REAL_ID).

Sonra yineleme

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

ve güncellemek sadece bu satırların için en düşük id bulabildiğim:

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

ben güncelleme deyimi biraz ayarlanmış olabilir emin değilim, ama umut bu fikri gösterir.

Avantaj, "temiz" bir tasarımdır (kimlik sütununuz gerçekten bir kimlik değildir) ve dizinin DB'ye özgü sürümlerine dayanmaktan daha taşınabilir bir çözümdür.

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