SQL bir anda Çoğalt bir satır Çıkarma

3 Cevap php

Ben şimdiye kadar meydana gelmiş tüm satır-değişiklikleri kaydetmek bir tablo var. Sorun uygulama başında her satır kopya bir demet yapılmış bir hata olduğunu olmasıdır.

Tablo şöyle:

copies
|ID |CID |DATA
| 1 | 1  |  DA
| 2 | 2  |  DO
| 2 | 3  |  DO (copy of CID 2)
| 1 | 4  |  DA (copy of CID 1)
| 2 | 5  |  DA
| 1 | 6  |  DA (copy of CID 1)
| 2 | 7  |  DO

CID tablo kopya benzersizdir.

İstediğim tek CID göre sınıflandırılmaktadır sonra başka bir kimliği BY DATA GROUP tüm çiftleri kaldırmaktır.

Eğer tabloda da görebileceğiniz gibi, CID 2 ve 3 aynıdır ve birbirleriyle peşinde. Ben CID 3 kaldırmak isterim aynı CID 4 ve CID 6 ile.; onlar arasında hiçbir kimliği 1 ve CID 1 kopyalarıdır.

Çiftleri çıkarılmasından sonra, ben tablo böyle bakmak istiyorum:

copies
|ID |CID |DATA
| 1 | 1  |  DA
| 2 | 2  |  DO
| 2 | 5  |  DA
| 2 | 7  |  DO

Herhangi bir öneriniz? :)

Ben cevap herkesin iyi olduğunu, bu sonucu verir düşünüyorum görünüyor çünkü benim soru kötü istendi düşünüyorum:

ID   | DATA | DATA | DATA | DATA | DATA |     DATA |        CID          |
                                                   |Expected |  Quassnoi |
1809 |    1 |    0 |    1 |    0 |    0 |     NULL |  252227 |    252227 |
1809 |    1 |    0 |    1 |    1 |    0 |     NULL |  381530 |    381530 |
1809 |    1 |    0 |    1 |    0 |    0 |     NULL |  438158 | (missing) |
1809 |    1 |    0 |    1 |    0 | 1535 | 20090113 |  581418 |    581418 |
1809 |    1 |    1 |    1 |    0 | 1535 | 20090113 |  581421 |    581421 |

CID 381.530 aralarında geliyor çünkü CID 252.227 VE CID 438.158 çoğaltır ama; Ben bunu tutmak istiyorum. Bu CID ve kimliği tarafından sipariş verirken birbirlerinden sonra doğrudan sadece çiftleri bulunuyor.

3 Cevap

DELETE   c.*
FROM     copies c
JOIN     (
         SELECT  id, data, MIN(copies) AS minc
         FROM    copies
         GROUP BY
                 id, data
         ) q
ON       c.id = q.id
         AND c.data = q.data
         AND c.cid <> q.minc

Update:

DELETE  c.*
FROM    (
        SELECT  cid
        FROM    (
                SELECT  cid,
                        COALESCE(data1 = @data1 AND data2 = @data2, FALSE) AS dup,
                        @data1 := data1,
                        @data2 := data2
                FROM    (
                        SELECT  @data1 := NULL,
                                @data2 := NULL
                        ) vars, copies ci
                ORDER BY
                        id, cid
                ) qi
        WHERE   dup
        ) q
JOIN    copies c
ON      c.cid = q.cid

Bu çözüm empoys MySQL oturum değişkenleri.

NOT EXISTS, ancak (o [{kullanmaz nedeniyle yol MySQL iyileştirici çalışmalar yavaş olacaktır kullanmak istiyorsunuz saf ANSI çözüm yoktur Bir ilişkili alt sorgu (3)]} erişim yöntemi).

Oldukça yakın bir görev için performans ayrıntıları için bloguma bu makaleye bakın:

Bunun için bir alt sorgu bir count kullanabilirsiniz:

delete from copies
where
    (select count(*) from copies s where s.id = copies.id 
                                   and s.data = copies.data 
                                   and s.cid > copies.cid) > 0

(max_cid olarak max (CID) seçmek id tarafından num> 1 grubu, veri kopyaları num gibi (*) saymak) in c.cid kopyalar c silin