Wyodrębnij tylko pierwszą z jednostki rekordu, w której jest zduplikowana wartość określonej kolumny
Zwykle, gdy wyodrębniasz tylko jeden zduplikowany rekord, pierwszą rzeczą, która przychodzi na myśl, jest distinct
to, że
distinct
Nie pozwala na określenie zduplikowanej kolumny i innej kolumny, które mają zostać pobrane w tym samym czasie.
Ponadto nie spełnia tego wymagania,distinct
ponieważ zawiera niezduplikowane rekordy w wyodrębnianiu.
Nie sądzę, żebyś mógł zrozumieć, co chcesz zrobić z samym tytułem, więc użyjmy przykładowego rekordu jako przykładu. To, co chcę zrobić, to następujący wynik ekstrakcji.
tożsamościNazwa | dowodu |
---|---|
1 | Imię 1 |
2 | Imię 2 |
3 | Imię 3 |
3 | Imię i nazwisko 3@example.com |
4 | Imię 4 Imię 4@example.com |
4 | Imię i nazwisko 4@example.com |
4 | Imię i nazwisko 4@example.com |
Zdobądź go w następujący sposób:
tożsamościNazwa | dowodu |
---|---|
3 | Imię i nazwisko 3@example.com |
4 | Imię i nazwisko 4@example.com |
Identyfikatory 1 i 2 nie są uwzględniane, ponieważ nie są duplikatami. Identyfikatory 3 i 4 są duplikatami, więc jeden z nich jest pobierany. Tym razem jednak nie otrzymamy pierwszego rekordu w kolejności przechowywania bazy danych. Ponadto załóżmy, że pierwszy wiersz nazwy ma być ułożony w kolejności priorytetu w warunkach, że "Nazwa zawiera znak @" i "Nazwa ma niewielką liczbę znaków".
Powyższy warunek można uzyskać za pomocą następującego kodu SQL. Używamy jednak podzapytań i nie sprawdziliśmy wydajności.
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)
)
Zduplikowane wiersze są having
sprawdzane za pomocą i count
. group by
Kluczowa kolumna, która ma być sprawdzana z zewnątrz, tutaj ID
kolumna jest where
zawężona przez .
Kolejność pierwszeństwa pobierania pierwszego wiersza jest order by
określona przez . charindex
Tutaj i len
sprawdź, czy zawiera określony znak i długość ciągu.
top
Wszystko, co musisz zrobić, to uzyskać pierwszy wiersz każdego zduplikowanego rekordu w .
Początkowo jest to w porządku, ale jeśli istnieją dwa lub więcej rekordów o dokładnie tej samej wartości, takich jak "ID: 4, Nazwa: Nazwa 4@example.com", nieuchronnie otrzymasz dwa rekordy.
row_number
W związku z tym jest dołączany tak, aby można go było zidentyfikować dla każdego wiersza za pomocą , dzięki czemu można pobrać tylko jeden rekord o dokładnie tej samej wartości.
Jeśli wiadomo, że dokładnie ten sam rekord nie istnieje, myślę, row_number
że lepiej byłoby sprawdzić wartości istniejących rekordów bez dołączania .
Jeśli istnieje wiele kluczy, które mają zostać sprawdzone pod kątem duplikatów, można zwiększyć liczbę kolumn kluczy dla każdego z nich. Rozważmy na przykład następujący rekord: Kolumny, które mają zostać sprawdzone pod kątem duplikatów, to 'ID1' i 'ID2'.
ID1 | ID2 | Nazwa |
---|---|---|
1 | 1 | Imię 1 |
2 | 1 | Imię 2 |
3 | 1 | Imię 31 |
3 | 2 | Imię 32 |
4 | 1 | Nazwa41 powiedział: |
4 | 2 | Nazwa42 powiedział: |
4 | 2 | Imię i nazwisko 4@example.com |
5 | 1 | Imię 555@example.com |
5 | 1 | Imię 55@example.com |
5 | 2 | Imię i nazwisko 5@example.com |
6 | 1 | Imię 6 |
6 | 1 | Imię i nazwisko 66@example.com |
6 | 2 | Imię 6 |
6 | 2 | Imię 6 |
Wynik przejęcia przedstawia się następująco.
ID1 | ID2 | Nazwa |
---|---|---|
4 | 2 | Imię i nazwisko 4@example.com |
5 | 1 | Imię 55@example.com |
6 | 1 | Imię i nazwisko 66@example.com |
6 | 2 | Imię 6 |
SQL wygląda tak: Możesz po prostu zwiększyć część, w której została określona kolumna klucza.
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)
)