Csak az elsőt vonja ki abból a rekordegységből, ahol a megadott oszlop értéke duplikálódik

Oldal frissítve :
Oldal létrehozásának dátuma :

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