Iš įrašo vieneto ištraukite tik pirmąjį, kuriame dubliuojama nurodyto stulpelio reikšmė
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)
)