Εξαγάγετε μόνο την πρώτη από τη μονάδα εγγραφής όπου η τιμή της καθορισμένης στήλης είναι διπλότυπη

Σελίδα ενημέρωση :
Ημερομηνία δημιουργίας σελίδας :

Κανονικά, όταν εξάγετε μόνο μία διπλή εγγραφή, το πρώτο πράγμα που έρχεται στο μυαλό είναι 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)
)