Как найти повторяющиеся значения в таблице в Oracle?

Какой самый простой оператор SQL вернет повторяющиеся значения для данного столбца и количество их вхождений в таблицу базы данных Oracle?

Например: у меня есть JOBS таблица со столбцом JOB_NUMBER. Как я могу узнать, есть ли у меня дубликаты JOB_NUMBER и сколько раз они дублируются?


person Andrew    schedule 12.09.2008    source источник
comment
другие решения stackoverflow.com/ questions / 4522431 /   -  person zloctb    schedule 19.08.2015


Ответы (12)


Агрегируйте столбец по COUNT, затем используйте предложение HAVING, чтобы найти значения, которые появляются более одного раза.

SELECT column_name, COUNT(column_name)
FROM table_name
GROUP BY column_name
HAVING COUNT(column_name) > 1;
person Bill the Lizard    schedule 12.09.2008
comment
Спасибо - это ответ, который я только что нашел, и вы превзошли меня, разместив его здесь! : o) - person Andrew; 12.09.2008
comment
Пожалуйста. Теперь я собираюсь опубликовать свой вопрос о различиях между count (столбец) и count (*). :) - person Bill the Lizard; 12.09.2008
comment
+1 через 4 года, по-прежнему работает хорошо, и его можно настроить для выбора нескольких столбцов, если они также находятся в group by, например: select column_one, column_two, count(*) from tablename group by column_one, column_two having count(column_one) > 1; и т. Д. - person Amos M. Carpenter; 24.09.2012
comment
или даже having count(*) > 1: D - person Stanislav Mamontov; 23.03.2015
comment
+1 более 8 лет спустя, по-прежнему хорошо работает как для последних версий Oracle, так и для MySQL (удалите пробел после функции счета в строке). - person PhatHV; 19.04.2016
comment
Этот скрипт всегда мне очень помогает! Спасибо, - person Gilberto Galea; 09.10.2018

Другой путь:

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

Работает нормально (достаточно быстро) при наличии индекса на column_name. И это лучший способ удалить или обновить повторяющиеся строки.

person Grrey    schedule 13.09.2008
comment
+1 хорошо работает для дубликатов нескольких столбцов (например, когда вы хотите добавить ограничение UNIQUE для нескольких столбцов), я нашел этот подход менее жестким, чем GROUP BY, чтобы перечислить повторяющиеся значения полей + другие поля, если необходимо. - person Frosty Z; 27.01.2012
comment
Просто чтобы прояснить (сначала это было неочевидно для меня) этот запрос возвращает только дубликаты, он не возвращает первую исходную запись, поэтому он хорошо работает для удаления дубликатов, основываясь на уникальном ограничении более чем 1 столбец. Вы можете выбрать повторяющиеся идентификаторы с помощью этого запроса, а затем использовать их для удаления дубликатов. - person matthewb; 21.11.2012
comment
если вы измените ‹на! =, вы получите все повторяющиеся записи. не только 2-я или 3-я запись - person moore1emu; 04.01.2019

Самое простое, что я могу придумать:

select job_number, count(*)
from jobs
group by job_number
having count(*) > 1;
person JosephStyons    schedule 12.09.2008
comment
Как я могу получить все столбцы? - person Asif Mushtaq; 26.12.2015
comment
выберите * из заданий, где задано_номер (выберите задание_номер из группы заданий по заданию_номер, имеющему счетчик (*) ›1) - person JosephStyons; 26.12.2015
comment
самое любимое решение ... лучше запоминать .. Я всегда люблю копировать .. спасибо @jo - person StartCoding; 22.07.2021

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

SELECT column_name
FROM table
GROUP BY column_name
HAVING COUNT(*) > 1
person Evan    schedule 13.09.2008

Как насчет:

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

Чтобы ответить на приведенный выше пример, это будет выглядеть так:

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

В случае, если несколько столбцов идентифицируют уникальную строку (например, таблицу отношений), вы можете использовать следующие

Используйте идентификатор строки, например 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);
person Jitendra Vispute    schedule 20.09.2012

Делает

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

даст вам дублированные идентификаторы строк.

person agnul    schedule 12.09.2008

Обычно я использую функцию Oracle Analytic ROW_NUMBER ().

Допустим, вы хотите проверить дубликаты уникального индекса или первичного ключа, построенного на столбцах (c1, c2, c3). Затем вы пойдете по этому пути, вызывая ROWID строк, в которых количество строк, добавленных 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)
person J. Chomel    schedule 24.10.2017

Я знаю, что это старый поток, но это может кому-то помочь.

Если вам нужно распечатать другие столбцы таблицы при проверке повторного использования ниже:

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;

также при необходимости можно добавить некоторые дополнительные фильтры в предложение where.

person Parth Kansara    schedule 23.07.2018

Вот SQL-запрос для этого:

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

1. решение

select * from emp
    where rowid not in
    (select max(rowid) from emp group by empno);
person DoOrDie    schedule 10.02.2016
comment
На этом оригинальном плакате ни разу не упоминалось об удалении, только подсчет - person Jeff; 10.02.2016

Также вы можете попробовать что-то вроде этого, чтобы перечислить все повторяющиеся значения в таблице, скажем, 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;
person Stacker    schedule 27.01.2016