Extrahujte iba prvý z jednotky záznamu, kde je hodnota zadaného stĺpca duplikovaná

Stránka aktualizovaná :
Dátum vytvorenia strany :

Normálne, keď extrahujem iba jeden duplicitný záznam, prvá vec, ktorá mi príde na myseľ, je distinct , že si myslím, distinct neumožňuje zadať duplicitný stĺpec a ďalší stĺpec, ktorý chcete načítať súčasne. Okrem toho nespĺňa túto požiadavku,distinct pretože do extrakcie zahŕňa neduplicitné záznamy.

Nemyslím si, že dokážete pochopiť, čo chcete robiť so samotným názvom, takže ako príklad použime vzorový záznam. Čo chcem urobiť, je nasledujúci výsledok extrakcie.

Názov preukazu totožnosti
1 Názov 1
2 Názov 2
3 Názov 3
3 Názov 3@example.com
4 Meno 4 Meno 4@example.com
4 Názov 4@example.com
4 Názov 4@example.com

Získajte ho nasledovne:

Názov preukazu totožnosti
3 Názov 3@example.com
4 Názov 4@example.com

ID 1 a 2 nie sú zahrnuté, pretože nie sú duplikátmi. ID 3 a 4 sú duplikáty, takže jeden z nich je získaný. Tentokrát však prvý záznam v poradí úložiska DB nezískame. Okrem toho predpokladajme, že chcete prvý riadok názvu v poradí podľa priority za podmienok "Názov obsahuje značku @" a "Názov má malý počet znakov".

Vyššie uvedenú podmienku je možné získať pomocou nasledujúceho SQL. Používame však poddotazy a výkon sme neskontrolovali.

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

Duplicitné riadky sa začiarknu having pomocou a count . group by Stĺpec kľúča, ktorý sa má skontrolovať zvonku, tu ID je where stĺpec zúžený o .

Poradie priority pri načítaní prvého riadka je order by určené parametrom . charindex Tu a len skontrolujte, či obsahuje zadaný znak a dĺžku reťazca. top Všetko, čo musíte urobiť, je dostať prvý riadok každého duplicitného záznamu do .

Pôvodne to bolo v poriadku, ale ak existujú dva alebo viac záznamov s presne rovnakou hodnotou, napríklad "ID: 4, Name: Name 4@example.com", nevyhnutne získate dva záznamy. row_number Preto je pripojený tak, aby ho bolo možné identifikovať pre každý riadok pomocou , aby bolo možné načítať iba jeden záznam s presne rovnakou hodnotou. Ak je známe, že presne ten istý záznam neexistuje, myslím, row_number že by bolo lepšie skontrolovať hodnoty existujúcich záznamov bez pripojenia .

Ak je potrebné skontrolovať duplikáty viacerých kľúčov, môžete zvýšiť počet stĺpcov kľúčov pre každý z nich. Zvážte napríklad nasledujúci záznam: Stĺpce, ktoré sa majú skontrolovať na duplikáty, sú "ID1" a "ID2".

ID1 ID2 Názov
1 1 Názov 1
2 1 Názov 2
3 1 Názov 31
3 2 Názov 32
4 1 Meno41
4 2 Meno42
4 2 Názov 4@example.com
5 1 Názov 555@example.com
5 1 Názov 55@example.com
5 2 Názov 5@example.com
6 1 Názov 6
6 1 Názov 66@example.com
6 2 Názov 6
6 2 Názov 6

Výsledok akvizície je nasledovný.

ID1 ID2 Názov
4 2 Názov 4@example.com
5 1 Názov 55@example.com
6 1 Názov 66@example.com
6 2 Názov 6

SQL vyzerá takto: Môžete jednoducho zväčšiť časť, kde bol zadaný kľúčový stĺpec.

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