Удаление повторяющихся строк из таблицы в Oracle
Я тестирую что-то в Oracle и заполнял таблицу некоторыми примерами данных, но в процессе я случайно загружал дубликаты записей, поэтому теперь я не могу создать первичный ключ, используя некоторые из столбцов.
Как удалить все повторяющиеся строки и оставить только один из них?
Ответы
Ответ 1
Использовать псевдокоманду rowid
.
DELETE FROM your_table
WHERE rowid not in
(SELECT MIN(rowid)
FROM your_table
GROUP BY column1, column2, column3);
Где column1
, column2
и column3
составляют идентификационный ключ для каждой записи. Вы можете указать все свои столбцы.
Ответ 2
Из Спросить 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);
(исправлена отсутствующая скобка)
Ответ 3
От DevX.com:
DELETE FROM our_table
WHERE rowid not in
(SELECT MIN(rowid)
FROM our_table
GROUP BY column1, column2, column3...) ;
Если столбец1, столбец2 и т.д. - это ключ, который вы хотите использовать.
Ответ 4
DELETE FROM tablename a
WHERE a.ROWID > ANY (SELECT b.ROWID
FROM tablename b
WHERE a.fieldname = b.fieldname
AND a.fieldname2 = b.fieldname2)
Ответ 5
Решение 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 );
Ответ 6
создать таблицу t2 в качестве выделенного выделения * из t1;
Ответ 7
Вам нужно сделать небольшой блок 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;
Ответ 8
Чтобы выбрать дубликаты, только формат запроса может быть:
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 Certified Associate (2008)
Ответ 9
Использование 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 );
Ответ 10
Решение 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
);
Ответ 11
1. Решение
delete from emp
where rowid not in
(select max(rowid) from emp group by empno);
2. sloution
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
);
Ответ 12
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
);
Ответ 13
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);
Ответ 14
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
Ответ 15
DELETE FROM tableName WHERE ROWID NOT IN (SELECT MIN (ROWID) FROM table GROUP BY columnname);
Ответ 16
delete from dept
where rowid in (
select rowid
from dept
minus
select max(rowid)
from dept
group by DEPTNO, DNAME, LOC
);
Ответ 17
Самый быстрый способ для действительно больших таблиц
-
Создать таблицу исключений со структурой ниже:
exceptions_table
ROW_ID ROWID
OWNER VARCHAR2(30)
TABLE_NAME VARCHAR2(30)
CONSTRAINT VARCHAR2(30)
-
Попробуйте создать уникальное ограничение или первичный ключ, который будет нарушен дублирующими элементами. Вы получите сообщение об ошибке, потому что у вас есть дубликаты. Таблица исключений будет содержать
rowids для повторяющихся строк.
alter table add constraint
unique --or primary key
(dupfield1,dupfield2) exceptions into exceptions_table;
-
Присоединитесь к своей таблице с помощью exceptions_table по rowid и удалите дубликаты
delete original_dups where rowid in (select ROW_ID from exceptions_table);
-
Если количество строк для удаления велико, то создайте новую таблицу (со всеми грантами и индексами), которая объединяется с 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 )
)
Ответ 18
Проверьте скрипты ниже -
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)
-
select * from test;
Вы увидите, что дубликаты записей были удалены.
Надеюсь, это решает ваш запрос.
Спасибо:)
Ответ 19
Я не видел ответов, которые бы использовали общие табличные выражения и оконные функции. Это то, с чем мне легче всего работать.
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) Добавлено поле "Сумма раздела" в запросе CTE, в котором каждая строка будет помечена номерами строк в группе. Поэтому для выбора строк с дубликатами, включая первый элемент, используйте "WHERE cnt> 1".
Ответ 20
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;
Ответ 21
Для лучшей производительности, вот что я написал:
(см. план выполнения)
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
);
Ответ 22
решение:
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
);