ฉันกำลังทดสอบบางอย่างใน Oracle และเติมตารางด้วยข้อมูลตัวอย่างบางส่วน แต่ในกระบวนการฉันโหลดระเบียนที่ซ้ำกันโดยไม่ได้ตั้งใจดังนั้นตอนนี้ฉันไม่สามารถสร้างคีย์หลักโดยใช้คอลัมน์บางคอลัมน์ได้
ฉันจะลบแถวที่ซ้ำกันทั้งหมดและปล่อยแถวเดียวได้อย่างไร
ฉันกำลังทดสอบบางอย่างใน Oracle และเติมตารางด้วยข้อมูลตัวอย่างบางส่วน แต่ในกระบวนการฉันโหลดระเบียนที่ซ้ำกันโดยไม่ได้ตั้งใจดังนั้นตอนนี้ฉันไม่สามารถสร้างคีย์หลักโดยใช้คอลัมน์บางคอลัมน์ได้
ฉันจะลบแถวที่ซ้ำกันทั้งหมดและปล่อยแถวเดียวได้อย่างไร
คำตอบ:
ใช้rowid
นามแฝง
DELETE FROM your_table
WHERE rowid not in
(SELECT MIN(rowid)
FROM your_table
GROUP BY column1, column2, column3);
ที่ไหนcolumn1
, column2
และcolumn3
ทำขึ้นที่สำคัญระบุสำหรับแต่ละระเบียน คุณอาจแสดงรายการคอลัมน์ทั้งหมดของคุณ
จาก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);
(แก้ไขวงเล็บที่หายไป)
จาก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)
delete from emp
where rowid not in
(select max(rowid) from emp group by empno);
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
);
delete from emp e1
where rowid not in
(select max(rowid) from emp e2
where e1.empno = e2.empno );
สร้างตาราง t2 เป็น select * ที่แตกต่างกันจาก t1;
distinct *
จะใช้ทุกระเบียนที่แตกต่างกันอย่างน้อย 1 สัญลักษณ์ใน 1 คอลัมน์ สิ่งที่คุณต้องทำก็คือเลือกค่าที่แตกต่างจากคอลัมน์ที่คุณต้องการสร้างคีย์หลัก - คำตอบของบิลเป็นตัวอย่างที่ดีของวิธีการนี้
คุณควรทำบล็อก 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
แบบสอบถามนี้จะเก็บบันทึกที่เก่าแก่ที่สุดในฐานข้อมูลสำหรับเกณฑ์ที่เลือกไว้ใน
Oracle Certified Associate (2008)
วิธีที่เร็วที่สุดสำหรับตารางที่ใหญ่จริงๆ
สร้างตารางข้อยกเว้นที่มีโครงสร้างด้านล่าง: 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 และลบ dups
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 )
)
ใช้ 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 );
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. 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
);
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
);
เพื่อประสิทธิภาพที่ดีที่สุดนี่คือสิ่งที่ฉันเขียน:
(ดูแผนปฏิบัติการ)
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
);
ตรวจสอบสคริปต์ด้านล่าง -
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 () = 1
3) คุณสามารถเปลี่ยนหมายเลขที่ซ้ำกันที่เก็บรักษาไว้โดยการเปลี่ยนสุดท้ายโดยใช้คำสั่ง "Where RN> N" ด้วย N> = 1 (ฉันคิดว่า N = 0 จะลบแถวทั้งหมดที่มีรายการซ้ำ แต่มันจะลบแถวทั้งหมด) .
4) เพิ่มเขตข้อมูลผลรวมของการสืบค้น CTE ซึ่งจะติดแท็กแต่ละแถวด้วยแถวจำนวนในกลุ่ม ดังนั้นในการเลือกแถวที่มีรายการซ้ำรวมถึงรายการแรกให้ใช้ "WHERE 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 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
);