Belirtilen sütunun değerinin çoğaltıldığı kayıt biriminden yalnızca ilkini ayıklayın

Sayfa güncel :
Sayfa oluşturma tarihi :

Normalde, yalnızca bir mükerrer kayıt çıkarırken akla distinct gelen ilk şey sanırım, distinct yinelenen bir sütunu ve aynı anda almak istediğiniz başka bir sütunu belirtmenize izin vermez. Ayrıca,distinct ayıklamada yinelenen olmayan kayıtlar içerdiğinden bu gereksinimi karşılamaz.

Sadece başlıkla ne yapmak istediğinizi anlayabileceğinizi sanmıyorum, bu yüzden örnek bir kayıt kullanalım. Yapmak istediğim şey aşağıdaki ekstraksiyon sonucu.

Kimlik Adı
1 İsim 1
2 İsim 2
3 İsim 3
3 İsim 3@example.com
4 İsim 4 İsim 4@example.com
4 İsim 4@example.com
4 İsim 4@example.com

Aşağıdaki gibi alın:

Kimlik Adı
3 İsim 3@example.com
4 İsim 4@example.com

1 ve 2 numaralı kimlikler, mükerrer olmadıkları için dahil edilmez. 3 ve 4 numaralı kimlikler mükerrerdir, bu nedenle bunlardan biri alınır. Ancak bu sefer DB depolama siparişinde ilk kaydı alamayacağız. Ayrıca, "Ad @ işareti içerir" ve "Ad az sayıda karaktere sahip" koşulları altında adın ilk satırını öncelik sırasına göre istediğinizi varsayalım.

Yukarıdaki koşul aşağıdaki SQL ile elde edilebilir. Ancak, alt sorgular kullanıyoruz ve performansı kontrol etmedik.

select
  *
from
  (select *, row_number() over(order by ID asc) as RowNum from SampleTable) tableMain
where tableMain.RowNum =
(
  select
    top(1) RowNum
  from
    (select *, row_number() over(order by ID asc) as RowNum from SampleTable) tableSub
  where
        tableMain.ID = tableSub.ID
    and exists ( 
      select
        *
      from
        SampleTable
      where
        tableSub.ID = ID
      having
        count(*) >= 2
    )
  order by
    case when charindex(N'@', Name) >= 1 then 0 else 1 end, len(Name)
)

Yinelenen satırlar ve count ile kontrol edilirhaving. group by Dışarıdan kontrol edilecek anahtar sütun, burada ID sütun ile daraltılırwhere.

İlk satırın order by alınması için öncelik sırası ile belirtilir. charindex Burada, belirtilen len karakteri ve dizenin uzunluğunu içerip içermediğini kontrol edin. top Tek yapmanız gereken, içindeki her yinelenen kaydın ilk satırını almaktır.

Başlangıçta bu iyidir, ancak "ID: 4, Name: Name 4@example.com" gibi tam olarak aynı değere sahip iki veya daha fazla kayıt varsa, kaçınılmaz olarak iki kayıt alırsınız. row_number Bu nedenle, ile her satır için tanımlanabilmesi için eklenir, böylece tam olarak aynı değere sahip yalnızca bir kayıt alınabilir. Aynı kaydın olmadığı biliniyorsa, row_number mevcut kayıtların değerlerini eklemeden kontrol etmenin daha iyi olacağını düşünüyorum.

Yinelenenleri kontrol etmek için birden fazla anahtar varsa, her biri için anahtar sütunlarının sayısını artırabilirsiniz. Örneğin, aşağıdaki kaydı göz önünde bulundurun: Kopyalar için kontrol edilecek sütunlar "ID1" ve "ID2"dir.

ID1 ID2 Adı
1 1 İsim 1
2 1 İsim 2
3 1 İsim 31
3 2 İsim 32
4 1 İsim41
4 2 İsim42
4 2 İsim 4@example.com
5 1 İsim 555@example.com
5 1 İsim 55@example.com
5 2 İsim 5@example.com
6 1 İsim 6
6 1 İsim 66@example.com
6 2 İsim 6
6 2 İsim 6

Satın alma sonucu aşağıdaki gibidir.

ID1 ID2 Adı
4 2 İsim 4@example.com
5 1 İsim 55@example.com
6 1 İsim 66@example.com
6 2 İsim 6

SQL şöyle görünür: Anahtar sütunun belirtildiği kısmı basitçe artırabilirsiniz.

select
  *
from
  (select *, row_number() over(order by ID1 asc, ID2 asc) as RowNum from SampleTable) tableMain
where tableMain.RowNum =
(
  select
    top(1) RowNum
  from
    (select *, row_number() over(order by ID1 asc, ID2 asc) as RowNum from SampleTable) tableSub
  where
        tableMain.ID1 = tableSub.ID1
    and tableMain.ID2 = tableSub.ID2
    and exists ( 
      select
        *
      from
        SampleTable
      where
            tableSub.ID1 = ID1
        and tableSub.ID2 = ID2
      having
        count(*) >= 2
    )
  order by
    case when charindex(N'@', Name) >= 1 then 0 else 1 end, len(Name)
)