إزالة الصفوف المكررة من الجدول في أوراكل
-
22-08-2019 - |
سؤال
إنني أختبر شيئًا ما في Oracle وقمت بملء جدول ببعض نماذج البيانات، ولكن أثناء العملية قمت بتحميل سجلات مكررة عن طريق الخطأ، لذا لا يمكنني الآن إنشاء مفتاح أساسي باستخدام بعض الأعمدة.
كيف يمكنني حذف جميع الصفوف المكررة وترك صف واحد فقط منها؟
المحلول
استخدم في pseudocolumn 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 );
وإنشاء جدول T2 كما حدد * متميزة من t1؛
ويتعين عليك أن تفعل كتلة 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)
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.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. الحل
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
);
أسرع طريقة للطاولات الكبيرة حقًا
قم بإنشاء جدول استثناء بالهيكل أدناه: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 ) )
تحقق من البرامج النصية أدناه -
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) إذا كان لديك سبب لاختيار مكررة واحد على الآخرين يمكنك استخدام جملة ORDER BY لجعل هذا الصف سوف يكون ROW_NUMBER () = 1
3) يمكنك تغيير مكررة عدد الحفاظ عليها عن طريق تغيير النهائي حيث شرط ل"أين RN> N" مع N> = 1 (كنت أفكر N = 0 هل حذف جميع الصفوف التي تحتوي على التكرارات، ولكن سيكون حذف فقط كافة الصفوف).
و4) اضيف مجال تقسيم مبلغ الاستعلام CTE التي سوف علامة كل صف مع الصفوف عدد في المجموعة. لذلك لتحديد الصفوف مع التكرارات، بما في ذلك استخدام البند الأول "حيث المركز الوطني للاستشعار> 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
);