Jak znaleźć zduplikowane wartości w tabeli w Oracle?

276

Jaka jest najprostsza instrukcja SQL, która zwróci zduplikowane wartości dla danej kolumny i liczbę ich wystąpień w tabeli bazy danych Oracle?

Na przykład: Mam JOBStabelę z kolumną JOB_NUMBER. Jak mogę się dowiedzieć, czy mam jakieś duplikaty JOB_NUMBERi ile razy są one duplikowane?

Andrzej
źródło
1
inne rozwiązania stackoverflow.com/questions/4522431/...
zloctb

Odpowiedzi:

608
SELECT column_name, COUNT(column_name)
FROM table_name
GROUP BY column_name
HAVING COUNT(column_name) > 1;
Bill jaszczurka
źródło
1
Dzięki - oto odpowiedź, którą właśnie znalazłem i pobiłaś mnie, że opublikowałem ją tutaj! : o)
Andrew
3
Nie ma za co. Teraz zamierzam opublikować własne pytanie dotyczące różnic między liczbą (kolumna) a liczbą (*). :)
Bill the Lizard
44
+1 ponad 4 lata później, nadal działa dobrze i można go dostosować do wybierania wielu kolumn, o ile są one również w group by, jak w: select column_one, column_two, count(*) from tablename group by column_one, column_two having count(column_one) > 1;itp.
Amos M. Carpenter
4
a nawet having count(*) > 1: D
Stanisław Mamontow
3
+1 ponad 8 lat później, nadal działa dobrze zarówno w najnowszych wersjach Oracle, jak i MySQL (usuń spację po zliczeniu w wierszu).
PhatHV
58

Inny sposób:

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

Działa dobrze (wystarczająco szybko), gdy jest włączony indeks column_name. To lepszy sposób na usunięcie lub aktualizację zduplikowanych wierszy.

Grrey
źródło
3
+1 działa dobrze dla duplikatów wielokolumnowych (np. Gdy chcesz dodać ograniczenie UNIQUE do kilku kolumn), znalazłem to podejście mniej „sztywne” niż GROUP BY, aby wyświetlić listę duplikatów wartości pól + inne pola, jeśli to konieczne.
Frosty Z
3
Żeby wyjaśnić (początkowo nie było to dla mnie oczywiste) to zapytanie zwraca tylko duplikaty, nie zwraca pierwszego oryginalnego wpisu, dlatego działa dobrze w usuwaniu duplikatów, w oparciu o unikalne ograniczenie ponad 1 kolumna. Za pomocą tego zapytania możesz wybrać duplikaty identyfikatorów, a następnie użyć ich do usunięcia duplikatów.
matthewb
1
jeśli zmienisz <na! = otrzymasz wszystkie rekordy, które się duplikują. nie tylko drugi lub trzeci rekord
moore1emu
33

Najprostszy, jaki mogę wymyślić:

select job_number, count(*)
from jobs
group by job_number
having count(*) > 1;
JosephStyons
źródło
1
Jak mogę uzyskać wszystkie kolumny?
Asif Mushtaq,
2
wybierz * z miejsc pracy, w których numer_zadania (wybierz numer_zadania z grupy zadań według numer_zadania o liczbie (*)> 1)
JosephStyons,
17

Nie musisz nawet mieć liczby w zwróconych kolumnach, jeśli nie musisz znać rzeczywistej liczby duplikatów. na przykład

SELECT column_name
FROM table
GROUP BY column_name
HAVING COUNT(*) > 1
Evan
źródło
7

Co powiesz na:

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

Aby odpowiedzieć na powyższy przykład, wyglądałoby to tak:

SELECT job_number, count(*)
FROM jobs
GROUP BY job_number HAVING COUNT(*) > 1;
Andrzej
źródło
5

W przypadku, gdy wiele kolumn identyfikuje unikalny wiersz (np. Tabela relacji), możesz użyć następujących

Użyj identyfikatora wiersza, np. Emp_dept (empid, deptid, startdate, enddate) załóżmy, że empid i deptid są unikalne i w takim przypadku określ wiersz

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

a jeśli taka tabela ma klucz podstawowy, użyj klucza podstawowego zamiast rowid, np. wtedy id to 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
źródło
4

Robić

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

poda ci zduplikowane identyfikatory wierszy.

agnul
źródło
4
SELECT   SocialSecurity_Number, Count(*) no_of_rows
FROM     SocialSecurity 
GROUP BY SocialSecurity_Number
HAVING   Count(*) > 1
Order by Count(*) desc 
Wahid Haidari
źródło
2

Zwykle używam funkcji Oracle Analytic ROW_NUMBER () .

Załóżmy, że chcesz sprawdzić duplikatów ty co unikatowy indeks lub klucz podstawowy zbudowany na kolumnach ( c1, c2, c3). Następnie pójdziesz tą drogą, przywołując ROWIDs wierszy, w których liczba wprowadzonych linii ROW_NUMBER()wynosi >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
źródło
1

Oto żądanie SQL, aby to zrobić:

select column_name, count(1)
from table
group by column_name
having count (column_name) > 1;
Chaminda Dilshan
źródło
1

Wiem, że to stary wątek, ale to może komuś pomóc.

Jeśli chcesz wydrukować inne kolumny tabeli podczas sprawdzania duplikatu, użyj poniżej:

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;

w razie potrzeby można również dodać dodatkowe filtry w klauzuli where.

Parth Kansara
źródło
0

1. rozwiązanie

select * from emp
    where rowid not in
    (select max(rowid) from emp group by empno);
DoOrDie
źródło
Ten oryginalny plakat nigdy nie wspominał o usunięciu, tylko się liczy
Jeff
-1

Możesz także spróbować czegoś takiego, aby wyświetlić listę wszystkich zduplikowanych wartości w tabeli, powiedz 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;
Układarka
źródło