Belirtilen sütunun değerinin çoğaltıldığı kayıt biriminden yalnızca ilkini ayıklayın
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)
)