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?


Odpowiedzi:


608
SELECT column_name, COUNT(column_name)
FROM table_name
GROUP BY column_name
HAVING COUNT(column_name) > 1;

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.


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;

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

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;

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

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.


4
SELECT   SocialSecurity_Number, Count(*) no_of_rows
FROM     SocialSecurity 
GROUP BY SocialSecurity_Number
HAVING   Count(*) > 1
Order by Count(*) desc 

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)

1

Oto żądanie SQL, aby to zrobić:

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

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.


0

1. rozwiązanie

select * from emp
    where rowid not in
    (select max(rowid) from emp group by empno);

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;
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.