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