Oracle のテーブルから重複行を削除する
-
22-08-2019 - |
質問
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
は、各レコードの識別キーを構成します。あなたは、すべての列を一覧表示することがあります。
他のヒント
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);
(固定欠落括弧)
DevX.comするから:
DELETE FROM our_table
WHERE rowid not in
(SELECT MIN(rowid)
FROM our_table
GROUP BY column1, column2, column3...) ;
どこなどcolumn1の、column2のは、あなたが使用するキーです。
DELETE FROM tablename a
WHERE a.ROWID > ANY (SELECT b.ROWID
FROM tablename b
WHERE a.fieldname = b.fieldname
AND a.fieldname2 = b.fieldname2)
ソリューション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 );
T1 SELECT * FROM別個としてテーブルT2を作成する;
あなたは、ループのカーソルを使用して、小さな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;
重複を選択するだけで、クエリの形式はすることができます:
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
に選ばれた基準のデータベース内の最も古い記録を保持します。
オラクル認定アソシエイト(2008)
ROWIDを使用 -
delete from emp
where rowid not in
(select max(rowid) from emp group by empno);
自己を使用して参加する -
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
);
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 );
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
);
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
);
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);
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
DELETE FROM tableName WHERE ROWID NOT IN (SELECT MIN (ROWID) FROM table GROUP BY columnname);
delete from dept
where rowid in (
select rowid
from dept
minus
select max(rowid)
from dept
group by DEPTNO, DNAME, LOC
);
本当に大きなテーブルを最速で作成する方法
以下の構造の例外テーブルを作成します。例外テーブル
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;
rowid によってテーブルを例外テーブルに結合し、重複を削除します
delete original_dups where rowid in (select ROW_ID from 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.
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.以下のクエリを実行します -
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;
重複したレコードが削除されたことがわかります。
これであなたの質問が解決されることを願っています。ありがとう :)
私は、共通テーブル式とウィンドウ関数を使用するすべての答えを見ていません。 これは私が作業するのが最も簡単見つけるものです。
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)あなたがROW_NUMBERを持つことになり、その行を作るためにORDER BY句を使用することができ、他の上に1つの重複を選択するためにいくつかの理由がある場合は()= 1
3)あなたは、最終的に変更して保存番号の重複を変更することができますwhere句に「どこRN> N」N> = 1(Iは、N = 0の重複を持っているすべての行を削除だろうと考えましたが、それは単に削除しますとすべての行)。
4)合計パーティションフィールドをグループ内の数字列と各行をタグ付けしますCTEクエリを追加しました。だから、「CNT> 1」最初の項目の使用を含め、重複、との行を選択します。
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;
最高のパフォーマンスを実現するために、ここで私が書いたものである。
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
);
ソリューション:
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
);