Belirli alanlardaki kopyaları bulmak için ifade seçin


415

Birden fazla alanda yinelenen kayıtlar bulmam için bana SQL ifadelerinde yardımcı olabilir misiniz?

Örneğin, sözde kodda:

select count(field1,field2,field3) 
from table 
where the combination of field1, field2, field3 occurs multiple times

ve yukarıdaki ifadeden birden fazla tekrarlama varsa , ilk kayıt hariç her kaydı seçmek istiyorum .


3
sahte kodunuz belirsizdir, ayrıca birincisini istemediğiniz sıralamayı tanımlamazsınız. bazı örnek veriler vermenizi öneririm.
mantıksızlık

Yanıtlar:


840

Birden çok kaydın bulunduğu alanların listesini almak için kullanabilirsiniz ..

select field1,field2,field3, count(*)
  from table_name
  group by field1,field2,field3
  having count(*) > 1

Satırların nasıl silineceği hakkında daha fazla bilgi için bu bağlantıyı kontrol edin.

http://support.microsoft.com/kb/139444

Düzenleme: Diğer kullanıcıların belirttiği gibi, yukarıdaki bağlantıdaki yaklaşımı kullanmadan önce "ilk satırları" nasıl tanımladığınıza karar vermek için bir ölçüt olmalıdır. Buna dayanarak, bir yan tümce sıralaması ve gerekirse bir alt sorgu kullanmanız gerekir. Bazı örnek veriler gönderebilirseniz, bu gerçekten yardımcı olacaktır.


42

"İlk" den bahsediyorsunuz, bu yüzden verilerinizde bir çeşit siparişiniz olduğunu varsayalım. Verilerinizin bir alan tarafından sipariş edildiğini varsayalım ID.

Bu SQL size birincisi dışında yinelenen girişleri almalıdır. Temel olarak (a) aynı alanlara ve (b) daha düşük bir kimliğe sahip başka bir satırın bulunduğu tüm satırları seçer. Performans iyi olmaz, ancak sorununuzu çözebilir.

SELECT A.ID, A.field1, A.field2, A.field3
  FROM myTable A
 WHERE EXISTS (SELECT B.ID
                 FROM myTable B
                WHERE B.field1 = A.field1
                  AND B.field2 = A.field2
                  AND B.field3 = A.field3
                  AND B.ID < A.ID)

17

Bu benim gibi SQL Server 2005 ile eğlenceli bir çözümdür. "İlk kayıt hariç her kayıt için" ile hangi satırın "ilk" olduğunu tanımlamak için kullanabileceğimiz başka bir "id" sütunu olduğunu varsayacağım.

SELECT id
    , field1
    , field2
    , field3
FROM
(
    SELECT id
        , field1
        , field2
        , field3
        , RANK() OVER (PARTITION BY field1, field2, field3 ORDER BY id ASC) AS [rank]
    FROM table_name
) a
WHERE [rank] > 1

SQL Server 2008 etiketini fark ettim. Önerimin hala geçerli olduğuna sevindim.
Nick Vaccaro

1
Mükemmel çözüm, çünkü aynı zamanda söz konusu tablodan silinmesi gereken satırları döndürür
Realto619

1
PARTITION BY alan listesini PK alanlarının bir listesi olarak düşünmeye yardımcı olur
bkwdesign

6

Yinelenen değerleri görmek için:

with MYCTE  as (
    select row_number() over ( partition by name  order by name) rown, *
    from tmptest  
    ) 
select * from MYCTE where rown <=1

3

SQL Server 2005 veya daha yenisini kullanıyorsanız (ve sorunuzun etiketleri SQL Server 2008'i gösteriyorsa), birleştirmeleri kullanmak bir nedenden dolayı daha az arzu edilir veya pratik değilse ilk kayıttan sonra yinelenen kayıtları döndürmek için sıralama işlevlerini kullanabilirsiniz. Aşağıdaki örnek bunu incelenirken göstermektedir ve burada incelenen sütunlardaki boş değerlerle çalışır.

create table Table1 (
 Field1 int,
 Field2 int,
 Field3 int,
 Field4 int 
)

insert  Table1 
values    (1,1,1,1)
        , (1,1,1,2)
        , (1,1,1,3)
        , (2,2,2,1)
        , (3,3,3,1)
        , (3,3,3,2)
        , (null, null, 2, 1)
        , (null, null, 2, 3)

select    *
from     (select      Field1
                    , Field2
                    , Field3
                    , Field4
                    , row_number() over (partition by   Field1
                                                      , Field2
                                                      , Field3
                                         order by       Field4) as occurrence
          from      Table1) x
where     occurrence > 1

Bu örnek çalıştırıldıktan sonra, her "gruptan" ilk kaydın hariç tutulduğuna ve null değerlere sahip kayıtların düzgün işlendiğine dikkat edin.

Bir grup içindeki kayıtları sipariş etmek için kullanılabilir bir sütununuz yoksa, bölümleme sütunlarını sipariş sütunları olarak kullanabilirsiniz.


1
CREATE TABLE #tmp
(
    sizeId Varchar(MAX)
)

INSERT  #tmp 
    VALUES ('44'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46')


SELECT * FROM #tmp
DECLARE @SqlStr VARCHAR(MAX)

SELECT @SqlStr = STUFF((SELECT ',' + sizeId
              FROM #tmp
              ORDER BY sizeId
              FOR XML PATH('')), 1, 1, '') 


SELECT TOP 1 * FROM (
select items, count(*)AS Occurrence
  FROM dbo.Split(@SqlStr,',')
  group by items
  having count(*) > 1
  )K
  ORDER BY K.Occurrence DESC    

0

her SELECT deyiminin sepratley sayısı için bu sorguyu deneyin:

select field1,count(field1) as field1Count,field2,count(field2) as field2Counts,field3, count(field3) as field3Counts
from table_name
group by field1,field2,field3
having count(*) > 1
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.