Εξαγάγετε μόνο την πρώτη από τη μονάδα εγγραφής όπου η τιμή της καθορισμένης στήλης είναι διπλότυπη
Κανονικά, όταν εξάγετε μόνο μία διπλή εγγραφή, το πρώτο πράγμα που έρχεται στο μυαλό είναι distinct
νομίζω,
distinct
Δεν σας επιτρέπει να καθορίσετε μια διπλότυπη στήλη και μια άλλη στήλη που θέλετε να ανακτήσετε ταυτόχρονα.
Επιπλέον, δεν ταιριάζει με αυτήν την απαίτηση,distinct
επειδή περιλαμβάνει μη διπλότυπες εγγραφές στην εξαγωγή.
Δεν νομίζω ότι μπορείτε να καταλάβετε τι θέλετε να κάνετε μόνο με τον τίτλο, οπότε ας χρησιμοποιήσουμε ένα δείγμα εγγραφής ως παράδειγμα. Αυτό που θέλω να κάνω είναι το ακόλουθο αποτέλεσμα εξαγωγής.
Όνομα | ταυτότητας |
---|---|
1 | Όνομα 1 |
2 | Όνομα 2 |
3 | Όνομα 3 |
3 | Όνομα 3@example.com |
4 | Όνομα 4 Όνομα 4@example.com |
4 | Όνομα 4@example.com |
4 | Όνομα 4@example.com |
Αποκτήστε το ως εξής:
Όνομα | ταυτότητας |
---|---|
3 | Όνομα 3@example.com |
4 | Όνομα 4@example.com |
Τα αναγνωριστικά 1 και 2 δεν περιλαμβάνονται επειδή δεν είναι διπλότυπα. Τα αναγνωριστικά 3 και 4 είναι διπλότυπα, επομένως ένα από αυτά ανακτάται. Ωστόσο, αυτή τη φορά, δεν θα λάβουμε την πρώτη εγγραφή στη σειρά αποθήκευσης DB. Επιπλέον, ας υποθέσουμε ότι θέλετε την πρώτη γραμμή του ονόματος με σειρά προτεραιότητας υπό τις συνθήκες ότι "Το όνομα περιέχει ένα @ mark" και "Το όνομα έχει μικρό αριθμό χαρακτήρων".
Η παραπάνω συνθήκη μπορεί να ληφθεί με την ακόλουθη SQL. Ωστόσο, χρησιμοποιούμε δευτερεύοντα ερωτήματα και δεν έχουμε ελέγξει την απόδοση.
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)
)
Οι having
διπλότυπες γραμμές ελέγχονται με και count
. group by
Η βασική στήλη που πρέπει να ελεγχθεί από έξω, εδώ ID
η στήλη where
περιορίζεται από .
Η σειρά προτεραιότητας για την ανάκτηση της πρώτης γραμμής order by
καθορίζεται από το . charindex
Εδώ και len
ελέγξτε αν περιέχει τον καθορισμένο χαρακτήρα και το μήκος της συμβολοσειράς.
top
Το μόνο που χρειάζεται να κάνετε είναι να λάβετε την πρώτη σειρά κάθε διπλότυπης εγγραφής στο .
Αρχικά, αυτό είναι εντάξει, αλλά εάν υπάρχουν δύο ή περισσότερες εγγραφές με ακριβώς την ίδια τιμή, όπως "ID: 4, Name: Name 4@example.com", αναπόφευκτα θα λάβετε δύο εγγραφές.
row_number
Επομένως, προσαρτάται έτσι ώστε να μπορεί να αναγνωριστεί για κάθε γραμμή με , έτσι ώστε να μπορεί να ανακτηθεί μόνο μία εγγραφή με ακριβώς την ίδια τιμή.
Εάν είναι γνωστό ότι δεν υπάρχει ακριβώς η ίδια εγγραφή, row_number
νομίζω ότι θα ήταν καλύτερο να ελέγξετε τις τιμές των υπαρχουσών εγγραφών χωρίς να προσαρτήσετε .
Εάν υπάρχουν πολλά κλειδιά που πρέπει να ελεγχθούν για διπλότυπα, μπορείτε να αυξήσετε τον αριθμό των στηλών κλειδιών για το καθένα. Για παράδειγμα, εξετάστε την ακόλουθη εγγραφή: Οι στήλες που πρέπει να ελεγχθούν για διπλότυπα είναι "ID1" και "ID2".
ID1 | ID2 | Όνομα |
---|---|---|
1 | 1 | Όνομα 1 |
2 | 1 | Όνομα 2 |
3 | 1 | Όνομα 31 |
3 | 2 | Όνομα 32 |
4 | 1 | Όνομα41 |
4 | 2 | Όνομα42 |
4 | 2 | Όνομα 4@example.com |
5 | 1 | Όνομα 555@example.com |
5 | 1 | Όνομα 55@example.com |
5 | 2 | Όνομα 5@example.com |
6 | 1 | Όνομα 6 |
6 | 1 | Όνομα 66@example.com |
6 | 2 | Όνομα 6 |
6 | 2 | Όνομα 6 |
Το αποτέλεσμα της εξαγοράς έχει ως εξής.
ID1 | ID2 | Όνομα |
---|---|---|
4 | 2 | Όνομα 4@example.com |
5 | 1 | Όνομα 55@example.com |
6 | 1 | Όνομα 66@example.com |
6 | 2 | Όνομα 6 |
Η SQL μοιάζει με αυτό: Μπορείτε απλά να αυξήσετε το τμήμα όπου καθορίστηκε η βασική στήλη.
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)
)