Ekstraktige ainult esimene kirjeüksusest, kus määratud veeru väärtus on dubleeritud
Tavaliselt tuleb ainult ühe duplikaatkirje ekstraheerimisel esimene asi, mis mulle meelde distinct
tuleb,
distinct
ei luba teil määrata duplikaatveergu ja teist veergu, mida soovite korraga tuua.
Lisaksdistinct
ei vasta see sellele nõudele, kuna see sisaldab ekstraktimisel mitteduplikaatkirjeid.
Ma arvan, et te ei saa aru, mida soovite ainult pealkirjaga teha, nii et kasutame näitena näidiskirjet. Mida ma tahan teha, on järgmine ekstraheerimise tulemus.
ID | nimi |
---|---|
1 | Nimi 1 |
2 | Nimi 2 |
3 | Nimi 3 |
3 | Nimi 3@example.com |
4 | Nimi 4 Nimi 4@example.com |
4 | Nimi 4@example.com |
4 | Nimi 4@example.com |
Hankige see järgmiselt:
ID | nimi |
---|---|
3 | Nimi 3@example.com |
4 | Nimi 4@example.com |
ID-sid 1 ja 2 ei kaasata, kuna need ei ole duplikaamid. ID-d 3 ja 4 on duplikaadid, nii et üks neist tuuakse välja. Kuid seekord ei saa me esimest kirjet DB salvestusjärjekorras. Lisaks oletame, et soovite nime esimest rida tähtsuse järjekorras tingimustel, et "Nimi sisaldab @-märki" ja "Nimel on väike arv märke".
Ülaltoodud tingimuse saab järgmise SQL-iga. Siiski kasutame alampäringuid ja pole jõudlust kontrollinud.
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)
)
Duplikaatridu kontrollitakse having
kombel ja . count
group by
Võtmeveerg, mida tuleb kontrollida väljastpoolt, siin ID
on where
veerg kitsendatud.
Esimese rea toomise järjestuse määrab order by
. charindex
Siin ja len
kontrollige, kas see sisaldab määratud märki ja stringi pikkust.
top
Kõik, mida pead tegema, on hankida iga duplikaatkirje esimene rida .
Algselt on see hea, kuid kui on kaks või enam kirjet, millel on täpselt sama väärtus, näiteks "ID: 4, Name: Name 4@example.com", saate paratamatult kaks kirjet.
row_number
Seetõttu lisatakse see nii, et seda saab iga rea jaoks tuvastada nupuga , nii et saab tuua ainult ühe täpselt sama väärtusega kirje.
Kui on teada, et täpselt sama kirjet pole olemas, arvan, et parem oleks kontrollida olemasolevate kirjete väärtusi ilma lisamata.row_number
Kui duplikaatide suhtes tuleb kontrollida mitut võtit, saate iga võtmeveergude arvu suurendada. Vaatleme näiteks järgmist kirjet: Duplikaatide suhtes kontrollitavad veerud on "ID1" ja "ID2".
ID1 | ID2 | nimi |
---|---|---|
1 | 1 | Nimi 1 |
2 | 1 | Nimi 2 |
3 | 1 | Nimi 31 |
3 | 2 | Nimi 32 |
4 | 1 | Nimi41 |
4 | 2 | Nimi42 |
4 | 2 | Nimi 4@example.com |
5 | 1 | Nimi 555@example.com |
5 | 1 | Nimi 55@example.com |
5 | 2 | Nimi 5@example.com |
6 | 1 | Nimi 6 |
6 | 1 | Nimi 66@example.com |
6 | 2 | Nimi 6 |
6 | 2 | Nimi 6 |
Omandamise tulemus on järgmine.
ID1 | ID2 | nimi |
---|---|---|
4 | 2 | Nimi 4@example.com |
5 | 1 | Nimi 55@example.com |
6 | 1 | Nimi 66@example.com |
6 | 2 | Nimi 6 |
SQL näeb välja selline: Saate lihtsalt suurendada osa, kus võtmeveerg määrati.
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)
)