Extrahujte iba prvý z jednotky záznamu, kde je hodnota zadaného stĺpca duplikovaná
Normálne, keď extrahujem iba jeden duplicitný záznam, prvá vec, ktorá mi príde na myseľ, je distinct
, že si myslím,
distinct
neumožňuje zadať duplicitný stĺpec a ďalší stĺpec, ktorý chcete načítať súčasne.
Okrem toho nespĺňa túto požiadavku,distinct
pretože do extrakcie zahŕňa neduplicitné záznamy.
Nemyslím si, že dokážete pochopiť, čo chcete robiť so samotným názvom, takže ako príklad použime vzorový záznam. Čo chcem urobiť, je nasledujúci výsledok extrakcie.
Názov | preukazu totožnosti |
---|---|
1 | Názov 1 |
2 | Názov 2 |
3 | Názov 3 |
3 | Názov 3@example.com |
4 | Meno 4 Meno 4@example.com |
4 | Názov 4@example.com |
4 | Názov 4@example.com |
Získajte ho nasledovne:
Názov | preukazu totožnosti |
---|---|
3 | Názov 3@example.com |
4 | Názov 4@example.com |
ID 1 a 2 nie sú zahrnuté, pretože nie sú duplikátmi. ID 3 a 4 sú duplikáty, takže jeden z nich je získaný. Tentokrát však prvý záznam v poradí úložiska DB nezískame. Okrem toho predpokladajme, že chcete prvý riadok názvu v poradí podľa priority za podmienok "Názov obsahuje značku @" a "Názov má malý počet znakov".
Vyššie uvedenú podmienku je možné získať pomocou nasledujúceho SQL. Používame však poddotazy a výkon sme neskontrolovali.
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)
)
Duplicitné riadky sa začiarknu having
pomocou a count
. group by
Stĺpec kľúča, ktorý sa má skontrolovať zvonku, tu ID
je where
stĺpec zúžený o .
Poradie priority pri načítaní prvého riadka je order by
určené parametrom . charindex
Tu a len
skontrolujte, či obsahuje zadaný znak a dĺžku reťazca.
top
Všetko, čo musíte urobiť, je dostať prvý riadok každého duplicitného záznamu do .
Pôvodne to bolo v poriadku, ale ak existujú dva alebo viac záznamov s presne rovnakou hodnotou, napríklad "ID: 4, Name: Name 4@example.com", nevyhnutne získate dva záznamy.
row_number
Preto je pripojený tak, aby ho bolo možné identifikovať pre každý riadok pomocou , aby bolo možné načítať iba jeden záznam s presne rovnakou hodnotou.
Ak je známe, že presne ten istý záznam neexistuje, myslím, row_number
že by bolo lepšie skontrolovať hodnoty existujúcich záznamov bez pripojenia .
Ak je potrebné skontrolovať duplikáty viacerých kľúčov, môžete zvýšiť počet stĺpcov kľúčov pre každý z nich. Zvážte napríklad nasledujúci záznam: Stĺpce, ktoré sa majú skontrolovať na duplikáty, sú "ID1" a "ID2".
ID1 | ID2 | Názov |
---|---|---|
1 | 1 | Názov 1 |
2 | 1 | Názov 2 |
3 | 1 | Názov 31 |
3 | 2 | Názov 32 |
4 | 1 | Meno41 |
4 | 2 | Meno42 |
4 | 2 | Názov 4@example.com |
5 | 1 | Názov 555@example.com |
5 | 1 | Názov 55@example.com |
5 | 2 | Názov 5@example.com |
6 | 1 | Názov 6 |
6 | 1 | Názov 66@example.com |
6 | 2 | Názov 6 |
6 | 2 | Názov 6 |
Výsledok akvizície je nasledovný.
ID1 | ID2 | Názov |
---|---|---|
4 | 2 | Názov 4@example.com |
5 | 1 | Názov 55@example.com |
6 | 1 | Názov 66@example.com |
6 | 2 | Názov 6 |
SQL vyzerá takto: Môžete jednoducho zväčšiť časť, kde bol zadaný kľúčový stĺpec.
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)
)