Izvlecite samo prvo iz enote zapisa, kjer je vrednost določenega stolpca podvojena
Običajno, ko izvlečete samo en podvojeni zapis, prva stvar, ki mi pride na misel, je distinct
, da pomislim:
distinct
ne omogoča določitve podvojenega stolpca in drugega stolpca, ki ga želite pridobiti hkrati.
Poleg tega ne ustreza tej zahtevi,distinct
ker v ekstrakcijo vključuje nepodvojene zapise.
Mislim, da ne morete razumeti, kaj želite storiti samo z naslovom, zato kot primer uporabimo vzorčni zapis. Kar želim narediti, je naslednji rezultat ekstrakcije.
Ime osebne izkaznice | |
---|---|
1 | Ime 1 |
2 | Ime 2 |
3 | Ime 3 |
3 | Ime 3@example.com |
4 | Ime 4 Ime 4@example.com |
4 | Ime 4@example.com |
4 | Ime 4@example.com |
Pridobite ga na naslednji način:
Ime osebne izkaznice | |
---|---|
3 | Ime 3@example.com |
4 | Ime 4@example.com |
ID-številki 1 in 2 nista vključena, ker nista dvojnika. ID 3 in 4 sta dvojnika, zato se pridobi eden od njih. Vendar tokrat ne bomo dobili prvega zapisa v vrstnem redu shranjevanja DB. Poleg tega predpostavimo, da želite prvo vrstico imena v prednostnem vrstnem redu pod pogoji, da »Ime vsebuje oznako @« in »Ime ima majhno število znakov«.
Zgornji pogoj lahko dobite z naslednjim SQL-jem. Vendar pa uporabljamo podpoizvedbe in nismo preverili učinkovitosti.
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)
)
Podvojene vrstice so označene having
z in count
. group by
Ključni stolpec, ki ga je treba preveriti od zunaj, je ID
stolpec where
zožen z .
Vrstni red prednosti za pridobivanje prve vrstice je order by
določen z . charindex
Tukaj in len
preverite, ali vsebuje določen znak in dolžino niza.
top
Vse, kar morate storiti, je, da dobite prvo vrstico vsakega podvojenega zapisa v .
Prvotno je to v redu, če pa obstajata dva ali več zapisov s popolnoma enako vrednostjo, na primer »ID: 4, Ime: Ime 4@example.com«, boste neizogibno dobili dva zapisa.
row_number
Zato je dodan tako, da ga je mogoče identificirati za vsako vrstico z , tako da je mogoče pridobiti samo en zapis s popolnoma enako vrednostjo.
Če je znano, da popolnoma isti zapis ne obstaja, mislim, da bi bilo bolje preveriti vrednosti obstoječih zapisov, row_number
ne da bi dodali .
Če je treba preveriti več ključev, ali so podvojeni, lahko povečate število stolpcev s ključi za vsakega od njih. Razmislite na primer o tem zapisu: Stolpca, ki jih je treba preveriti za dvojnike, sta »ID1« in »ID2«.
ID1 | ID2 | ime |
---|---|---|
1 | 1 | Ime 1 |
2 | 1 | Ime 2 |
3 | 1 | Ime 31 |
3 | 2 | Ime 32 |
4 | 1 | Ime41 |
4 | 2 | Ime42 |
4 | 2 | Ime 4@example.com |
5 | 1 | Ime 555@example.com |
5 | 1 | Ime 55@example.com |
5 | 2 | Ime 5@example.com |
6 | 1 | Ime 6 |
6 | 1 | Ime 66@example.com |
6 | 2 | Ime 6 |
6 | 2 | Ime 6 |
Rezultat prevzema je naslednji.
ID1 | ID2 | ime |
---|---|---|
4 | 2 | Ime 4@example.com |
5 | 1 | Ime 55@example.com |
6 | 1 | Ime 66@example.com |
6 | 2 | Ime 6 |
SQL izgleda takole: Lahko preprosto povečate del, kjer je bil določen ključni stolpec.
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)
)