Wie finde ich doppelte Werte in einer Tabelle in Oracle?

276

Was ist die einfachste SQL-Anweisung, die die doppelten Werte für eine bestimmte Spalte und die Anzahl ihrer Vorkommen in einer Oracle-Datenbanktabelle zurückgibt?

Zum Beispiel: Ich habe eine JOBSTabelle mit der Spalte JOB_NUMBER. Wie kann ich herausfinden, ob ich Duplikate habe JOB_NUMBERund wie oft diese dupliziert werden?

Andrew
quelle
1
andere Lösungen stackoverflow.com/questions/4522431/…
zloctb

Antworten:

608
SELECT column_name, COUNT(column_name)
FROM table_name
GROUP BY column_name
HAVING COUNT(column_name) > 1;
Bill die Eidechse
quelle
1
Danke - das ist die Antwort, die ich gerade gefunden habe und du hast mich geschlagen, sie wieder hier zu posten! : o)
Andrew
3
Bitte. Jetzt werde ich meine eigene Frage zu den Unterschieden zwischen Anzahl (Spalte) und Anzahl (*) stellen. :)
Bill the Lizard
44
+1 über 4 Jahre später, funktioniert immer noch gut und kann für die Auswahl mehrerer Spalten angepasst werden, solange diese auch in der group by, wie in: select column_one, column_two, count(*) from tablename group by column_one, column_two having count(column_one) > 1;usw.
Amos M. Carpenter
4
oder sogar having count(*) > 1: D
Stanislav Mamontov
3
+1 über 8 Jahre später funktioniert immer noch gut für die neuesten Versionen von Oracle und MySQL (entfernen Sie Leerzeichen nach der Zählfunktion in der Zeile).
PhatHV
58

Ein anderer Weg:

SELECT *
FROM TABLE A
WHERE EXISTS (
  SELECT 1 FROM TABLE
  WHERE COLUMN_NAME = A.COLUMN_NAME
  AND ROWID < A.ROWID
)

Funktioniert gut (schnell genug), wenn ein Index aktiviert ist column_name. Und es ist besser, doppelte Zeilen zu löschen oder zu aktualisieren.

Grrey
quelle
3
+1 funktioniert gut für mehrspaltige Duplikate (z. B. wenn Sie eine EINZIGARTIGE Einschränkung für mehrere Spalten hinzufügen möchten). Ich fand diesen Ansatz weniger "starr" als den GROUP BY-Ansatz, um die doppelten Feldwerte + andere Felder aufzulisten, falls erforderlich.
Frosty Z
3
Nur um zu verdeutlichen (dies war mir zunächst nicht klar), gibt diese Abfrage nur die Duplikate zurück. Sie gibt nicht den ersten ursprünglichen Eintrag zurück, weshalb sie gut zum Löschen der Duplikate geeignet ist, basierend auf einer eindeutigen Einschränkung über mehr als 1 Spalte. Sie können die doppelten IDs mit dieser Abfrage auswählen und diese dann zum Löschen der doppelten IDs verwenden.
Matthewb
1
Wenn Sie <in! = ändern, erhalten Sie alle Datensätze, die dupliziert werden. nicht nur die 2. oder 3. Aufzeichnung
moore1emu
33

Am einfachsten kann ich mir vorstellen:

select job_number, count(*)
from jobs
group by job_number
having count(*) > 1;
JosephStyons
quelle
1
Wie kann ich alle Spalten erhalten?
Asif Mushtaq
2
Wählen Sie * aus Jobs, in denen job_number in (wählen Sie job_number aus der Jobgruppe nach job_number mit count (*)> 1)
JosephStyons
17

Sie müssen nicht einmal die Anzahl in den zurückgegebenen Spalten haben, wenn Sie die tatsächliche Anzahl der Duplikate nicht kennen müssen. z.B

SELECT column_name
FROM table
GROUP BY column_name
HAVING COUNT(*) > 1
Evan
quelle
7

Wie wäre es mit:

SELECT <column>, count(*)
FROM <table>
GROUP BY <column> HAVING COUNT(*) > 1;

Um das obige Beispiel zu beantworten, würde es so aussehen:

SELECT job_number, count(*)
FROM jobs
GROUP BY job_number HAVING COUNT(*) > 1;
Andrew
quelle
5

Wenn mehrere Spalten eine eindeutige Zeile (z. B. Beziehungstabelle) identifizieren, können Sie Folgendes verwenden

Verwenden Sie die Zeilen-ID, z. B. emp_dept (empid, deptid, startdate, enddate). Nehmen Sie an, dass empid und deptid eindeutig sind, und identifizieren Sie in diesem Fall die Zeile

select oed.empid, count(oed.empid) 
from emp_dept oed 
where exists ( select * 
               from  emp_dept ied 
                where oed.rowid <> ied.rowid and 
                       ied.empid = oed.empid and 
                      ied.deptid = oed.deptid )  
        group by oed.empid having count(oed.empid) > 1 order by count(oed.empid);

und wenn eine solche Tabelle einen Primärschlüssel hat, verwenden Sie den Primärschlüssel anstelle der Zeilen-ID, z. B. ist id dann pk

select oed.empid, count(oed.empid) 
from emp_dept oed 
where exists ( select * 
               from  emp_dept ied 
                where oed.id <> ied.id and 
                       ied.empid = oed.empid and 
                      ied.deptid = oed.deptid )  
        group by oed.empid having count(oed.empid) > 1 order by count(oed.empid);
Jitendra Vispute
quelle
4

Tun

select count(j1.job_number), j1.job_number, j1.id, j2.id
from   jobs j1 join jobs j2 on (j1.job_numer = j2.job_number)
where  j1.id != j2.id
group by j1.job_number

gibt Ihnen die IDs der duplizierten Zeilen.

agnul
quelle
4
SELECT   SocialSecurity_Number, Count(*) no_of_rows
FROM     SocialSecurity 
GROUP BY SocialSecurity_Number
HAVING   Count(*) > 1
Order by Count(*) desc 
Wahid Haidari
quelle
2

Normalerweise verwende ich die Oracle Analytic- Funktion ROW_NUMBER () .

Sagen Sie bitte die Duplikate überprüfen möchten Sie haben in Bezug auf einen eindeutigen Index oder Primärschlüssel gebaut auf Spalten ( c1, c2, c3). Dann gehen Sie diesen Weg und rufen ROWIDs von Zeilen auf, wobei die Anzahl der eingebrachten Zeilen ROW_NUMBER()ist >1:

Select * From Table_With_Duplicates
      Where Rowid In
                    (Select Rowid
                       From (Select Rowid,
                                    ROW_NUMBER() Over (
                                            Partition By c1 || c2 || c3
                                            Order By c1 || c2 || c3
                                        ) nbLines
                               From Table_With_Duplicates) t2
                      Where nbLines > 1)
J. Chomel
quelle
1

Hier ist eine SQL-Anfrage, um dies zu tun:

select column_name, count(1)
from table
group by column_name
having count (column_name) > 1;
Chaminda Dilshan
quelle
1

Ich weiß, dass es ein alter Thread ist, aber das kann jemandem helfen.

Wenn Sie andere Spalten der Tabelle drucken müssen, während Sie nach doppelten Verwendungszwecken suchen:

select * from table where column_name in
(select ing.column_name from table ing group by ing.column_name having count(*) > 1)
order by column_name desc;

Bei Bedarf können in der where-Klausel auch einige zusätzliche Filter hinzugefügt werden.

Parth Kansara
quelle
0

1. Lösung

select * from emp
    where rowid not in
    (select max(rowid) from emp group by empno);
DoOrDie
quelle
Dieses Originalplakat erwähnte nie das Löschen, nur das Zählen
Jeff
-1

Sie können auch so etwas versuchen, um alle doppelten Werte in einer Tabelle aufzulisten, z. B. reqitem

SELECT count(poid) 
FROM poitem 
WHERE poid = 50 
AND rownum < any (SELECT count(*)  FROM poitem WHERE poid = 50) 
GROUP BY poid 
MINUS
SELECT count(poid) 
FROM poitem 
WHERE poid in (50)
GROUP BY poid 
HAVING count(poid) > 1;
Stapler
quelle