Oracle: удаление повторяющихся строк, сравнение Исключение столбца ID [дубликат]

Если .NET 4 доступен вам, посмотрите: http://visitmix.com/writings/the-rise-of-json (archive.org)

Вот фрагмент с этого сайта:

WebClient webClient = new WebClient();
dynamic result = JsonValue.Parse(webClient.DownloadString("https://api.foursquare.com/v2/users/self?oauth_token=XXXXXXX"));
Console.WriteLine(result.response.user.firstName);

Что последнее Console.WriteLine довольно мила ...

111
задан Sam 17 August 2014 в 14:54
поделиться

19 ответов

Используйте псевдоколонку rowid.

DELETE FROM your_table
WHERE rowid not in
(SELECT MIN(rowid)
FROM your_table
GROUP BY column1, column2, column3);

Где column1, column2 и column3 составляют идентификационный ключ для каждой записи. Вы можете указать все свои столбцы.

228
ответ дан Bill the Lizard 31 August 2018 в 13:42
поделиться

Для лучшей производительности, вот что я написал: (см. план выполнения)

DELETE FROM your_table
WHERE rowid IN 
  (select t1.rowid from your_table  t1
      LEFT OUTER JOIN (
      SELECT MIN(rowid) as rowid, column1,column2, column3
      FROM your_table 
      GROUP BY column1, column2, column3
  )  co1 ON (t1.rowid = co1.rowid)
  WHERE co1.rowid IS NULL
);
0
ответ дан AlexB 31 August 2018 в 13:42
поделиться

Я не видел ответов, которые используют общие выражения таблиц и функции окна. Это то, с чем мне легче всего работать.

DELETE FROM
 YourTable
WHERE
 ROWID IN
    (WITH Duplicates
          AS (SELECT
               ROWID RID, 
               ROW_NUMBER() 
               OVER(
               PARTITION BY First_Name, Last_Name, Birth_Date)
                  AS RN
               SUM(1)
               OVER(
               PARTITION BY First_Name, Last_Name, Birth_Date
               ORDER BY ROWID ROWS BETWEEN UNBOUNDED PRECEDING 
                                       AND UNBOUNDED FOLLOWING)
                   AS CNT
              FROM
               YourTable
              WHERE
               Load_Date IS NULL)
     SELECT
      RID
     FROM
      duplicates
     WHERE
      RN > 1);

Что следует отметить:

1) Мы проверяем только дублирование полей в предложении раздела.

2) Если у вас есть повод выбрать один дубликат над другими, вы можете использовать предложение order by, чтобы эта строка имела row_number () = 1

3) Вы можете изменить дубликат числа, сохраненный, изменив окончательное предложение where на «Where RN> N "с N> = 1 (я думал, что N = 0 удалит все строки с дубликатами, но просто удалит все строки).

4) Добавлено поле раздела Sum, запрос CTE который помечает каждую строку номерами строк в группе. Поэтому для выбора строк с дубликатами, включая первый элемент, используйте «WHERE cnt> 1».

1
ответ дан Darrel Lee 31 August 2018 в 13:42
поделиться

Из Ask Tom

delete from t
 where rowid IN ( select rid
                    from (select rowid rid, 
                                 row_number() over (partition by 
                         companyid, agentid, class , status, terminationdate
                                   order by rowid) rn
                            from t)
                   where rn <> 1);

(исправлено отсутствующая скобка)

12
ответ дан David Balažic 31 August 2018 в 13:42
поделиться
[Д0] 5. решение

delete from emp where rowid in 
    (
      select  rid from
       (
         select rowid rid,rank() over (partition by emp_id order by rowid)rn from emp     
       )
     where rn > 1
    );
2
ответ дан DoOrDie 31 August 2018 в 13:42
поделиться

Решение 1)

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

Решение 2)

delete from emp where rowid in
               (
                 select rid from
                  (
                    select rowid rid,
                      row_number() over(partition by empno order by empno) rn
                      from emp
                  )
                where rn > 1
               );

Решение 3)

delete from emp e1
         where rowid not in
          (select max(rowid) from emp e2
           where e1.empno = e2.empno ); 
5
ответ дан huzeyfe 31 August 2018 в 13:42
поделиться
DELETE FROM tableName  WHERE ROWID NOT IN (SELECT   MIN (ROWID) FROM table GROUP BY columnname);
1
ответ дан JgSudhakar 31 August 2018 в 13:42
поделиться
create table abcd(id number(10),name varchar2(20))

insert into abcd values(1,'abc')

insert into abcd values(2,'pqr')


insert into abcd values(3,'xyz')

insert into abcd values(1,'abc')

insert into abcd values(2,'pqr')

insert into abcd values(3,'xyz')


select * from abcd
id  Name
1   abc
2   pqr
3   xyz
1   abc
2   pqr
3   xyz

Delete Duplicate record but keep Distinct Record in table 

DELETE 
FROM abcd a
WHERE ROWID > (SELECT MIN(ROWID) FROM abcd b
WHERE b.id=a.id
);

run the above query 3 rows delete 

select * from abcd

id  Name 
1   abc
2   pqr
3   xyz
1
ответ дан Krunal Patel 31 August 2018 в 13:42
поделиться

Из DevX.com :

DELETE FROM our_table
WHERE rowid not in
(SELECT MIN(rowid)
FROM our_table
GROUP BY column1, column2, column3...) ;

Где column1, column2 и т. д. - это ключ, который вы хотите использовать.

11
ответ дан Mark 31 August 2018 в 13:42
поделиться
DELETE from table_name where rowid not in (select min(rowid) FROM table_name group by column_name);

, и вы также можете удалить повторяющиеся записи другим способом

DELETE from table_name a where rowid > (select min(rowid) FROM table_name b where a.column=b.column);
2
ответ дан Md Wasi 31 August 2018 в 13:42
поделиться

создать таблицу t2 как выбрать отдельный * из t1;

6
ответ дан Mohammed khaled 31 August 2018 в 13:42
поделиться
delete from dept
where rowid in (
     select rowid
     from dept
     minus
     select max(rowid)
     from dept
     group by DEPTNO, DNAME, LOC
);
1
ответ дан Nic Wortel 31 August 2018 в 13:42
поделиться

Вы должны сделать небольшой блок pl / sql с помощью курсора для цикла и удалить строки, которые вы не хотите сохранять. Например:

declare
prev_var my_table.var1%TYPE;

begin

for t in (select var1 from my_table order by var 1) LOOP

-- if previous var equal current var, delete the row, else keep on going.
end loop;

end;
1
ответ дан Nick 31 August 2018 в 13:42
поделиться

Проверьте скрипты ниже -

1.

Create table test(id int,sal int); 

2.

    insert into test values(1,100);    
    insert into test values(1,100);    
    insert into test values(2,200);    
    insert into test values(2,200);    
    insert into test values(3,300);    
    insert into test values(3,300);    
    commit;

3.

 select * from test;    

Вы увидите здесь 6 записей. 4.run ниже запроса -

delete from 
   test
where rowid in
 (select rowid from 
   (select 
     rowid,
     row_number()
    over 
     (partition by id order by sal) dup
    from test)
  where dup > 1)
  1. select * from test;

Вы увидите, что дубликаты записей были удалены. Надеюсь, это решает ваш запрос. Спасибо :)

1
ответ дан Nikhil Manapure 31 August 2018 в 13:42
поделиться

Использование rowid -

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

Использование self join -

delete from emp e1
 where rowid not in
 (select max(rowid) from emp e2
 where e1.empno = e2.empno );
2
ответ дан NSNoob 31 August 2018 в 13:42
поделиться
create or replace procedure delete_duplicate_enq as
    cursor c1 is
    select *
    from enquiry;
begin
    for z in c1 loop
        delete enquiry
        where enquiry.enquiryno = z.enquiryno
        and rowid > any
        (select rowid
        from enquiry
        where enquiry.enquiryno = z.enquiryno);
    end loop;
 end delete_duplicate_enq;
0
ответ дан Radim Köhler 31 August 2018 в 13:42
поделиться

Для выбора дубликатов только формат запроса может быть:

SELECT GroupFunction(column1), GroupFunction(column2),..., 
COUNT(column1), column1, column2...
FROM our_table
GROUP BY column1, column2, column3...
HAVING COUNT(column1) > 1

Таким образом, правильный запрос в соответствии с другим предложением:

DELETE FROM tablename a
      WHERE a.ROWID > ANY (SELECT b.ROWID
                             FROM tablename b
                            WHERE a.fieldname = b.fieldname
                              AND a.fieldname2 = b.fieldname2
                              AND ....so on.. to identify the duplicate rows....)

Этот запрос будет содержать самый старый запись в базе данных для критериев, выбранных в WHERE CLAUSE.

Сертифицированный специалист Oracle (2008)

3
ответ дан rationalboss 31 August 2018 в 13:42
поделиться

Самый быстрый способ для действительно больших таблиц

  1. Создать таблицу исключений со структурой ниже: exceptions_table
    ROW_ID ROWID
    OWNER VARCHAR2(30)
    TABLE_NAME VARCHAR2(30)
    CONSTRAINT VARCHAR2(30)
    
  2. Попробуйте создать уникальное ограничение или первичный ключ, который будет нарушен по дубликатам. Вы получите сообщение об ошибке, потому что у вас есть дубликаты. Таблица исключений будет содержать rowids для повторяющихся строк.
    alter table add constraint
    unique --or primary key
    (dupfield1,dupfield2) exceptions into exceptions_table;
    
  3. Присоединитесь к вашей таблице с помощью exceptions_table по rowid и delete dups
    delete original_dups where rowid in (select ROW_ID from exceptions_table);
    
  4. Если количество строк для удаления велико, тогда создайте новую таблицу (со всеми грантами и индексы), которые объединяются с exceptions_table по rowid и переименовывают исходную таблицу в таблицу original_dups и переименовывают new_table_with_no_dups в исходную таблицу
    create table new_table_with_no_dups AS (
        select field1, field2 ........ 
        from original_dups t1
        where not exists ( select null from exceptions_table T2 where t1.rowid = t2.row_id )
    )
    
1
ответ дан Stephen Ostermiller 31 August 2018 в 13:42
поделиться
[Д0] 1. решение

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

2. решение

delete from emp where rowid in
               (
                 select rid from
                  (
                    select rowid rid,
                      row_number() over(partition by empno order by empno) rn
                      from emp
                  )
                where rn > 1
               );

3.solution

delete from emp e1
         where rowid not in
          (select max(rowid) from emp e2
           where e1.empno = e2.empno ); 

4. решение

 delete from emp where rowid in
            (
             select rid from
                (
                  select rowid rid,
                  dense_rank() over(partition by empno order by rowid
                ) rn
             from emp
            )
 where rn > 1
);
2
ответ дан user 31 August 2018 в 13:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: