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

191

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

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

Теги:

11 ответов

452
Лучший ответ
select column_name, count(column_name)
from table
group by column_name
having count (column_name) > 1;
  • 1
    Спасибо - это ответ, который я только что нашел, и ты побил меня, чтобы опубликовать его здесь! : О)
  • 3
    Пожалуйста. Теперь я собираюсь опубликовать свой собственный вопрос о различиях между количеством (столбец) и количеством (*). :)
Показать ещё 5 комментариев
40

Другой способ:

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, чтобы вывести список значений дубликатов полей + другие поля, если это необходимо.
  • 3
    Просто чтобы уточнить (сначала это не было очевидно для меня), этот запрос возвращает только дубликаты, он не возвращает первую исходную запись, поэтому он хорошо работает для удаления дубликатов, основываясь на уникальном ограничении для более чем 1 столбец. С помощью этого запроса вы можете выбрать идентификаторы дубликатов, а затем использовать их для удаления дубликатов.
Показать ещё 1 комментарий
25

Проще всего я могу думать:

select job_number, count(*)
from jobs
group by job_number
having count(*) > 1;
  • 1
    Как я могу получить все столбцы?
  • 2
    выберите * из заданий, в которых задан номер задания (выберите задание из группы заданий по номеру задания, имеющему количество (*)> 1)
12

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

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

Как насчет:

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

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

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

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

Использовать идентификатор строки например 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);
  • 0
    Хорошая дополнительная информация.
3
SELECT   SocialSecurity_Number, Count(*) no_of_rows
FROM     SocialSecurity 
GROUP BY SocialSecurity_Number
HAVING   Count(*) > 1
Order by Count(*) desc 
3

Выполнение

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

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

0

Я обычно использую Функция 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)
0

1. Решение

select * from emp
    where rowid not in
    (select max(rowid) from emp group by empno);
  • 0
    Этот оригинальный постер никогда не упоминал удаление, только подсчет
-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;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню