Izvilkt tikai pirmo no ieraksta vienības, kurā tiek dublēta norādītās kolonnas vērtība
Parasti, iegūstot tikai vienu ieraksta dublikātu, pirmais, kas nāk prātā, manuprāt, ir distinct
distinct
Neļauj norādīt dublētu kolonnu un citu kolonnu, kuru vēlaties izgūt vienlaikus.
Turklāt neatbilst šai prasībai,distinct
jo ekstrakcijā ir iekļauti ieraksti, kas nedublējas.
Es nedomāju, ka jūs varat saprast, ko vēlaties darīt tikai ar nosaukumu, tāpēc kā piemēru izmantosim ieraksta paraugu. Tas, ko es gribu darīt, ir šāds ekstrakcijas rezultāts.
ID | nosaukums |
---|---|
1 | Vārds 1 |
2 | Vārds 2 |
3 | Vārds 3 |
3 | Nosaukums 3@example.com |
4 | Vārds 4 Vārds 4@example.com |
4 | Nosaukums 4@example.com |
4 | Nosaukums 4@example.com |
Iegūstiet to šādi:
ID | nosaukums |
---|---|
3 | Nosaukums 3@example.com |
4 | Nosaukums 4@example.com |
ID 1 un 2 nav iekļauti, jo tie nav dublikāti. ID 3 un 4 ir dublikāti, tāpēc viens no tiem tiek izgūts. Tomēr šoreiz mēs nesaņemsim pirmo ierakstu DB krātuves pasūtījumā. Turklāt pieņemsim, ka vēlaties vārda pirmo rindu prioritārā secībā ar nosacījumiem, ka "Vārds satur zīmi @" un "Vārdam ir neliels rakstzīmju skaits".
Iepriekš minēto nosacījumu var iegūt ar šādu SQL. Tomēr mēs izmantojam apakšvaicājumus un neesam pārbaudījuši veiktspēju.
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)
)
Rindu dublikāti tiek having
pārbaudīti ar un count
. group by
Atslēgas kolonna, kas jāpārbauda no ārpuses, šeit ID
kolonna ir where
sašaurināta ar .
Pirmās rindas izgūšanas prioritātes secību nosaka order by
ar . charindex
Šeit un len
pārbaudiet, vai tajā ir norādītā rakstzīme un virknes garums.
top
Viss, kas jums jādara, ir iegūt katra ieraksta dublikāta pirmo rindu .
Sākotnēji tas ir labi, bet, ja ir divi vai vairāki ieraksti ar tieši tādu pašu vērtību, piemēram, "ID: 4, Vārds: Vārds 4@example.com", jūs neizbēgami iegūsit divus ierakstus.
row_number
Tāpēc tas ir pievienots tā, lai to varētu identificēt katrai rindai ar , lai varētu izgūt tikai vienu ierakstu ar tieši tādu pašu vērtību.
Ja ir zināms, ka tieši tāds pats ieraksts nepastāv, es row_number
domāju, ka labāk būtu pārbaudīt esošo ierakstu vērtības, nepievienojot .
Ja ir jāpārbauda vairākas atslēgas, lai atrastu dublikātus, varat palielināt atslēgu kolonnu skaitu katrai no tām. Piemēram, apsveriet šādu ierakstu: Pārbaudāmās kolonnas ir "ID1" un "ID2".
ID1 | ID2 | nosaukums |
---|---|---|
1 | 1 | Vārds 1 |
2 | 1 | Vārds 2 |
3 | 1 | Vārds 31 |
3 | 2 | Vārds 32 |
4 | 1 | Vārds41 |
4 | 2 | Vārds42 |
4 | 2 | Nosaukums 4@example.com |
5 | 1 | Nosaukums 555@example.com |
5 | 1 | Nosaukums 55@example.com |
5 | 2 | Nosaukums 5@example.com |
6 | 1 | Vārds 6 |
6 | 1 | Nosaukums 66@example.com |
6 | 2 | Vārds 6 |
6 | 2 | Vārds 6 |
Iegādes rezultāts ir šāds.
ID1 | ID2 | nosaukums |
---|---|---|
4 | 2 | Nosaukums 4@example.com |
5 | 1 | Nosaukums 55@example.com |
6 | 1 | Nosaukums 66@example.com |
6 | 2 | Vārds 6 |
SQL izskatās šādi: Jūs varat vienkārši palielināt daļu, kurā tika norādīta atslēgas kolonna.
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)
)