Csak az elsőt vonja ki abból a rekordegységből, ahol a megadott oszlop értéke duplikálódik
Normális esetben, ha csak egy duplikált rekordot bontok ki, az első dolog, ami eszembe jut, az az distinct
, hogy azt hiszem:
distinct
nem teszi lehetővé ismétlődő oszlop és egy másik lekérni kívánt oszlop egyidejű megadását.
Ezenkívüldistinct
nem felel meg ennek a követelménynek, mert nem ismétlődő rekordokat tartalmaz a kinyerésben.
Nem hiszem, hogy csak a címmel meg tudod érteni, mit akarsz kezdeni, ezért vegyünk példaként egy mintarekordot. Amit tenni akarok, az a következő extrakciós eredmény.
Azonosító | neve |
---|---|
1 | 1. név |
2 | 2. név |
3 | 3. név |
3 | Név 3@example.com |
4 | Név 4 Név 4@example.com |
4 | Név 4@example.com |
4 | Név 4@example.com |
Szerezd meg az alábbiak szerint:
Azonosító | neve |
---|---|
3 | Név 3@example.com |
4 | Név 4@example.com |
Az 1-es és 2-es azonosítók nem szerepelnek benne, mert nem ismétlődőek. A 3. és 4. azonosító ismétlődő példány, így az egyik lekérésre kerül. Ezúttal azonban nem kapjuk meg az első rekordot az adatbázis tárolási sorrendjében. Tegyük fel továbbá, hogy a név első sorát prioritási sorrendben szeretné a "Név @ jelet tartalmaz" és a "Név kevés karaktert tartalmaz" feltételek mellett.
A fenti feltétel a következő SQL-lel érhető el. Azonban segédlekérdezéseket használunk, és nem ellenőriztük a teljesítményt.
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)
)
Az ismétlődő sorokat a és a count
jellel ellenőrzi.having
group by
A kívülről ellenőrizendő kulcsoszlop, itt ID
az oszlopot where
szűkítik .
Az első sor order by
lekérésének elsőbbségi sorrendjét a . charindex
Itt ellenőrizze, hogy len
tartalmazza-e a megadott karaktert és a karakterlánc hosszát.
top
Mindössze annyit kell tennie, hogy minden ismétlődő rekord első sorát beolvassa .
Eredetileg ez rendben van, de ha két vagy több rekord pontosan azonos értékkel rendelkezik, például "ID: 4, Név: Név 4@example.com", akkor elkerülhetetlenül két rekordot kap.
row_number
Ezért a rendszer úgy fűzi hozzá, hogy minden sorban azonosítható legyen a jellel, így csak egy pontosan azonos értékű rekord kérhető le.
Ha ismert, hogy pontosan ugyanaz a rekord nem létezik, úgy gondolom row_number
, hogy jobb lenne ellenőrizni a meglévő rekordok értékeit anélkül, hogy hozzáfűznénk .
Ha több kulcsot kell ellenőrizni az ismétlődések szempontjából, növelheti mindegyikhez tartozó kulcsoszlopok számát. Vegyük például a következő rekordot: Az ismétlődések szempontjából ellenőrizendő oszlopok az "ID1" és az "ID2".
ID1 | ID2 | név |
---|---|---|
1 | 1 | 1. név |
2 | 1 | 2. név |
3 | 1 | Név 31 |
3 | 2 | Név 32 |
4 | 1 | Név41 |
4 | 2 | Név42 |
4 | 2 | Név 4@example.com |
5 | 1 | Név 555@example.com |
5 | 1 | Név 55@example.com |
5 | 2 | Név 5@example.com |
6 | 1 | Név 6 |
6 | 1 | Név 66@example.com |
6 | 2 | Név 6 |
6 | 2 | Név 6 |
Az akvizíció eredménye a következő.
ID1 | ID2 | név |
---|---|---|
4 | 2 | Név 4@example.com |
5 | 1 | Név 55@example.com |
6 | 1 | Név 66@example.com |
6 | 2 | Név 6 |
Az SQL így néz ki: Egyszerűen növelheti azt a részt, ahol a kulcsoszlop meg lett adva.
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)
)