Poimi vain ensimmäinen tietueyksiköstä, jossa määritetyn sarakkeen arvo on monistettu
Normaalisti, kun poimit vain yhden päällekkäisen tietueen, ensimmäinen asia, joka tulee mieleen, on distinct
:
distinct
Ei salli sinun määrittää sarakkeen kaksoiskappaletta ja toista saraketta, jonka haluat noutaa samanaikaisesti.
Lisäksidistinct
ei vastaa tätä vaatimusta, koska se sisältää poiminnassa tietueita, jotka eivät ole päällekkäisiä.
En usko, että ymmärrät, mitä haluat tehdä pelkällä otsikolla, joten käytetään esimerkkitietuetta esimerkkinä. Haluan tehdä seuraavan uuttotuloksen.
Tunnuksen | nimi |
---|---|
1 | Nimi 1 |
2 | Nimi 2 |
3 | Nimi 3 |
3 | Nimi 3@example.com |
4 | Nimi 4 Nimi 4@example.com |
4 | Nimi 4@example.com |
4 | Nimi 4@example.com |
Hanki se seuraavasti:
Tunnuksen | nimi |
---|---|
3 | Nimi 3@example.com |
4 | Nimi 4@example.com |
Tunnukset 1 ja 2 eivät sisälly, koska ne eivät ole kaksoiskappaleita. Tunnukset 3 ja 4 ovat kaksoiskappaleita, joten yksi niistä noudetaan. Tällä kertaa emme kuitenkaan saa ensimmäistä tietuetta DB-tallennustilaukseen. Oletetaan lisäksi, että haluat nimen ensimmäisen rivin tärkeysjärjestyksessä ehdoilla, että "Nimi sisältää @-merkin" ja "Nimessä on pieni määrä merkkejä".
Yllä oleva ehto voidaan saada seuraavalla SQL:llä. Käytämme kuitenkin alikyselyitä, emmekä ole tarkistaneet suorituskykyä.
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)
)
Rivien kaksoiskappaleet tarkistetaan having
komennoilla ja . count
group by
Ulkopuolelta tarkistettava avainsarake, tässä ID
sarake on kavennettu where
.
Ensimmäisen rivin noutamisen tärkeysjärjestys on order by
määritetty . charindex
Tässä ja len
tarkista, sisältääkö se määritetyn merkin ja merkkijonon pituuden.
top
Sinun tarvitsee vain saada kunkin tietueen kaksoiskappaleen ensimmäinen rivi .
Alun perin tämä on hyvä, mutta jos on kaksi tai useampia tietueita, joilla on täsmälleen sama arvo, kuten "ID: 4, Name: Name 4@example.com", saat väistämättä kaksi tietuetta.
row_number
Siksi se liitetään siten, että se voidaan tunnistaa kullekin riville merkillä , jotta vain yksi tietue, jolla on täsmälleen sama arvo, voidaan noutaa.
Jos tiedetään, että täsmälleen samaa tietuetta ei ole olemassa, row_number
mielestäni olisi parempi tarkistaa olemassa olevien tietueiden arvot liittämättä .
Jos kaksoiskappaleiden varalta tarkistetaan useita avaimia, voit lisätä avainsarakkeiden määrää kullekin avaimelle. Tarkastellaan esimerkiksi seuraavaa tietuetta: Kaksoiskappaleiden varalta tarkistettavat sarakkeet ovat "ID1" ja "ID2".
ID1 | ID2-nimi | |
---|---|---|
1 | 1 | Nimi 1 |
2 | 1 | Nimi 2 |
3 | 1 | Nimi 31 |
3 | 2 | Nimi 32 |
4 | 1 | Nimi41 |
4 | 2 | Nimi42 |
4 | 2 | Nimi 4@example.com |
5 | 1 | Nimi 555@example.com |
5 | 1 | Nimi 55@example.com |
5 | 2 | Nimi 5@example.com |
6 | 1 | Nimi 6 |
6 | 1 | Nimi 66@example.com |
6 | 2 | Nimi 6 |
6 | 2 | Nimi 6 |
Yritysoston tulos on seuraava.
ID1 | ID2-nimi | |
---|---|---|
4 | 2 | Nimi 4@example.com |
5 | 1 | Nimi 55@example.com |
6 | 1 | Nimi 66@example.com |
6 | 2 | Nimi 6 |
SQL näyttää tältä: Voit yksinkertaisesti suurentaa osaa, jossa avainsarake on määritetty.
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)
)