Iš įrašo vieneto ištraukite tik pirmąjį, kuriame dubliuojama nurodyto stulpelio reikšmė

Puslapis atnaujintas :
Puslapio sukūrimo data :

Paprastai, išgaunant tik vieną pasikartojantį įrašą, pirmas dalykas, kuris ateina į galvą, yra distinct tai, kad manau, distinct neleidžia nurodyti pasikartojančio stulpelio ir kito stulpelio, kurį norite gauti tuo pačiu metu. Be to, neatitinka šio reikalavimo,distinct nes į ekstrakciją įtraukiami nedubliuojami įrašai.

Nemanau, kad galite suprasti, ką norite daryti vien su pavadinimu, todėl kaip pavyzdį naudokime pavyzdinį įrašą. Tai, ką noriu padaryti, yra toks ekstrahavimo rezultatas.

ID pavadinimas
1 Vardas 1
2 Vardas 2
3 Vardas 3
3 Vardas 3@example.com
4 Vardas 4 Vardas 4@example.com
4 Vardas 4@example.com
4 Vardas 4@example.com

Gaukite jį taip:

ID pavadinimas
3 Vardas 3@example.com
4 Vardas 4@example.com

1 ir 2 ID neįtraukiami, nes jie nėra dublikatai. 3 ir 4 ID yra dublikatai, todėl vienas iš jų yra nuskaitomas. Tačiau šį kartą pirmojo įrašo DB saugojimo tvarkoje negausime. Be to, tarkime, kad norite, kad pirmoji vardo eilutė būtų išdėstyta prioriteto tvarka tokiomis sąlygomis, kad "Pavadinime yra @ ženklas" ir "Vardas turi nedaug simbolių".

Pirmiau nurodytą sąlygą galima gauti naudojant šį SQL. Tačiau mes naudojame antrines užklausas ir nepatikrinome našumo.

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

Pasikartojančios eilutės tikrinamos having su ir count . group by Rakto stulpelis, kurį reikia patikrinti iš išorės, čia ID stulpelis susiaurintas where .

Pirmosios eilutės order by gavimo eiliškumo tvarką nurodo . charindex Čia ir len patikrinkite, ar jame yra nurodytas simbolis ir eilutės ilgis. top Viskas, ką jums reikia padaryti, tai gauti pirmąją kiekvieno pasikartojančio įrašo eilutę .

Iš pradžių tai gerai, bet jei yra du ar daugiau įrašų, turinčių tą pačią vertę, pvz., "ID: 4, Name: Name 4@example.com", neišvengiamai gausite du įrašus. row_number Todėl jis pridedamas taip, kad jį būtų galima identifikuoti kiekvienai eilutei su , kad būtų galima gauti tik vieną įrašą su lygiai tokia pačia reikšme. Jei žinoma, kad to paties įrašo nėra, manau, row_number kad geriau būtų patikrinti esamų įrašų reikšmes be pridėjimo .

Jei reikia patikrinti, ar yra keli raktai, ar nėra dublikatų, galite padidinti kiekvieno iš jų raktų stulpelių skaičių. Pavyzdžiui, apsvarstykite šį įrašą: Stulpeliai, kuriuos reikia patikrinti, ar nėra dublikatų, yra "ID1" ir "ID2".

ID1 ID2 pavadinimas
1 1 Vardas 1
2 1 Vardas 2
3 1 Vardas 31
3 2 Vardas 32
4 1 Vardas41
4 2 Vardas42
4 2 Vardas 4@example.com
5 1 Vardas 555@example.com
5 1 Pavadinimas 55@example.com
5 2 Vardas 5@example.com
6 1 Vardas 6
6 1 Vardas 66@example.com
6 2 Vardas 6
6 2 Vardas 6

Įsigijimo rezultatas yra toks.

ID1 ID2 pavadinimas
4 2 Vardas 4@example.com
5 1 Pavadinimas 55@example.com
6 1 Vardas 66@example.com
6 2 Vardas 6

SQL atrodo taip: Galite tiesiog padidinti dalį, kurioje buvo nurodytas rakto stulpelis.

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