Як знайти дублюючі значення в таблиці в Oracle?


276

Який найпростіший оператор SQL, який повертає дублікати значень для даного стовпця та кількість їх виникнення в таблиці бази даних Oracle?

Наприклад: у мене є JOBSтаблиця зі стовпцем JOB_NUMBER. Як я можу дізнатися, чи є у мене дублікати JOB_NUMBERs, і скільки разів вони дублюються?


Відповіді:


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

1
Дякую - ось відповідь, яку я щойно знайшов, і ти побив мене, щоб опублікувати її тут! : o)
Андрій

3
Ласкаво просимо. Зараз я збираюся опублікувати власне запитання про відмінності між count (стовпець) та count (*). :)
Білл Ящірка

44
+1 понад 4 роки пізніше все ще працює добре, і його можна налаштувати для вибору декількох стовпців, якщо вони також знаходяться в group by, як у: select column_one, column_two, count(*) from tablename group by column_one, column_two having count(column_one) > 1;тощо.
Амос М. Карпентер,

4
або навіть having count(*) > 1: D
Станіслав Мамонтов

3
+1 за 8 років пізніше, як і раніше, працює як для останніх версій Oracle, так і для MySQL (видаліть пробіл після функції підрахунку у рядку).
PhatHV

58

Інший спосіб:

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

Працює чудово (досить швидко), коли індекс включений column_name. І краще спосіб видалити або оновити повторювані рядки.


3
+1 добре працює для дублікатів у декількох стовпцях (наприклад, коли ви хочете додати UNIQUE обмеження для кількох стовпців), я вважав цей підхід менш "жорстким", ніж GROUP BY один, щоб перерахувати значення дублікатів поля + інші поля, якщо потрібно.
Морозний Z

3
Просто для уточнення (це мені спочатку не було очевидно) цей запит повертає лише дублікати, він не повертає першу оригінальну запис, тому він добре працює для видалення дублікатів на основі унікального обмеження більше, ніж 1 стовпець. Ви можете вибрати дублікати ідентифікаторів за допомогою цього запиту, а потім використовувати їх для видалення дублікатів.
matthewb

1
якщо ви зміните <на! =, ви отримаєте всі записи, які дублюються. не просто 2-й чи 3-й запис
moore1emu

33

Найпростіше, про що я можу придумати:

select job_number, count(*)
from jobs
group by job_number
having count(*) > 1;

1
Як я можу отримати всі стовпці?
Асиф Муштак

2
виберіть * з вакансій, у яких робота_кілька в (виберіть кількість робочих чисел із групи робочих місць за кількістю робочих номерів, що мають кількість (*)> 1)
JosephStyons

17

Вам не потрібно навіть рахувати у повернених стовпцях, якщо вам не потрібно знати фактичну кількість дублікатів. напр

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

7

Як щодо:

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

Щоб відповісти на приклад вище, це виглядатиме так:

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

5

У випадку, коли кілька стовпців ідентифікують унікальний рядок (наприклад, таблиця відносин), ви можете використовувати наступне

Використовуйте ідентифікатор рядка, наприклад, emp_dept (empid, deptid, startdate, enddate), припустимо, що empid і deptid є унікальними і ідентифікуйте рядок у цьому випадку

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

і якщо така таблиця має первинний ключ, тоді використовуйте первинний ключ замість rowid, наприклад id тоді 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

Робимо

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

дасть вам дублюються ідентифікатори рядків.



2

Зазвичай я використовую функцію Oracle Analytic ROW_NUMBER () .

Припустимо , ви хочете , щоб перевірити дублікати ви щодо унікальний індекс або первинний ключ , побудований на колонах ( c1, c2, c3). Тоді ви будете йти по цьому шляху, в результаті чого до ROWIDS рядків , де кількість рядків принесли ROW_NUMBER()є >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

Я знаю, що це стара тема, але це може допомогти комусь.

Якщо вам потрібно роздрукувати інші стовпці таблиці, перевіряючи використання дубліката нижче:

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;

також можна додати кілька додаткових фільтрів у пункті, де потрібно.


0

1. рішення

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

Цей оригінальний афіша жодного разу не згадував про видалення, лише підрахунок
Джефф

-1

Також ви можете спробувати щось подібне, щоб перелічити всі повторювані значення в таблиці, наприклад, 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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.