Ekstraktige ainult esimene kirjeüksusest, kus määratud veeru väärtus on dubleeritud

Lehekülg uuendatud :
Lehe loomise kuupäev :

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)
)