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


277

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

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


1
других решений stackoverflow.com/questions/4522431/...
zloctb

Ответы:


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

1
Спасибо - это ответ, который я только что нашел, и ты побил меня, чтобы опубликовать его здесь! : o)
Андрей

3
Пожалуйста. Теперь я собираюсь опубликовать свой собственный вопрос о различиях между количеством (столбец) и количеством (*). :)
Билл Ящерица

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 вместо rowid, например, id is 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 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;

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


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.