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

#sql #oracle #duplicates

#sql #Oracle #дубликаты

Вопрос:

Я хочу создать инструкцию, которая останавливается и возвращает true в ту же секунду, когда находит повторяющееся значение в столбце. Мне все равно, какое значение, и мне просто нужно знать, существует дубликат или нет; больше ничего.

Я знаю, что могу писать Select count(*) from myTable group by primary_id having count(*) > 1; , но это касается каждой отдельной строки таблицы, тогда как я хочу, чтобы запрос останавливался, как только он обнаруживает единственный случай существования дубликата.

Лучший из известных мне вариантов заключается в следующем:-

  select 1 as thingy from dual outer_qry
 where exists
 (
    select * from
      (
       select some_ID, 
              case when COUNT(*) > 1 then 'X' else 'N' end as TRIG 
       from myTable 
       group by some_ID
       )INNER_QRY
       where INNER_QRY.trig = outer_qry.dummy 
 );
  

Однако это занимает 13 секунд, и я сомневаюсь, что на поиск первого дубликата уйдет столько времени.

Кто-нибудь, пожалуйста, может подсказать, где я ошибаюсь, поскольку, надеюсь, исходя из моего SQL, я предполагаю, что функция EXISTS будет проверяться для каждой строки, возвращаемой для inner_qry, но, похоже, это не так.

Ответ №1:

Вы бы использовали exists . Это возвращает все дубликаты:

 select t.*
from mytable t
where exists (select 1
              from mytable t t2
              where t2.some_id = t.some_id and t2.rowid <> t.rowid
             );
  

В Oracle 12c вы бы добавили fetch first 1 row only . И он может использовать индекс на mytable(some_id) .

В более ранних версиях:

 select 1 as HasDuplicate
from (select t.*
      from mytable t
      where exists (select 1
                    from mytable t t2
                    where t2.some_id = t.some_id and t2.rowid <> t.rowid
                   )
     ) t
where rownum = 1;
  

Если это не возвращает строк, значит, дубликатов нет.

Комментарии:

1. Спасибо, что нашли время правильно прочитать это и понять проблему, прежде чем предлагать решение. Работает отлично (y)

Ответ №2:

 select * from table1 t1 natural join table1 t2 where t1.rowid < t2.rowid;
  

Комментарии:

1. Как решение с помощью join может быть быстрее, чем GROUP BY и HAVING COUNT(*) > 1 ?

Ответ №3:

вы можете использовать это, чтобы понять, что id является дубликатом

    select some_ID 
   from myTable 
   group by some_ID having count(*) >1
  

Комментарии:

1. В вопросе я объясняю, что это не то, что я ищу.