Removing duplicate records by using Oracle’s ROWID

ถ้าคุณมีตารางข้อมูลอยู่ และรู้ว่ามีบางแถวที่มีข้อมูลซ้ำซ้อนกัน ทางไหนเป็นวิธีที่ดีที่จะสามารถหาและกำจัดแถวที่มีข้อมูลซ้ำนี้ออกไปจากตารางของฐานข้อมูล Oracle ?

 

การหาแถวที่มีข้อมูลซ้ำซ้อน

เราสามารถหาข้อมูลแถวที่มีข้อมูลซ้ำซ้อนกันได้โดยใช้คำสั่ง select ดังนี้

 

select a,b,count(*)

from test

group by a,b

having count(*) > 1;

ผลลัพธ์ที่ได้ :

A          B   COUNT(*)

———- ———- ———-

1          2        259

2          2          5

 

จากตัวอย่างในตาราง test นี้เราจะกำหนดว่าให้ค่าในคอลัมภ์ a และ b จะต้องมีค่าไม่ซ้ำ ซึ่งผลลัพธ์ที่ปรากฏคือ มีข้อมูลซ้ำ 258 แถว และ 4 แถว

 

การกำจัดแถวที่มีข้อมูลซ้ำซ้อน
เราสามารถกำจัดแถวที่มีข้อมูลซ้ำซ้อนกันได้โดยการใช้ rowid เข้ามาช่วย คราวนี้คุณต้องเลือกว่าจะเลือกเก็บข้อมูลแถวไหนไว้

เราลองมาดูข้อมูลที่ควรจะเป็นที่ไม่ซ้ำกันว่ามีข้อมูลอะไรบ้าง โดยสามารถใช้คำสั่งได้ดังนี้

select a,b,count(*) from test

group by a,b;

A          B   COUNT(*)

———- ———- ———-

1          2        259

2          2          5

3          0          1

 

กรณีที่ต้องการลบและคงเหลือไว้เฉพาะแถวแรกที่ซ้ำสามารถใช้คำสั่งได้ดังนี้

 

เราต้องการกำจัด 258 แถวที่ซึ่ง A = 1 และ B = 2 บวกกับ

— 4 แถวที่ซึ่ง A = 2 และ B = 2

ลองมา select แถวที่เราจะคงไว้ดูก่อน

select min(rowid),a,b from test

group by a,b;

MIN(ROWID)                             A          B

——————————- ———- ———-

AAAAyvAAGAAAABYAAA          1          2

AAAAyvAAGAAAABYAED          2          2

AAAAyvAAGAAAABYAEI           3          0

 

— คราวนี้ก็ถึงเวลาลบข้อมูลกันแล้ว

— เริ่มกันเลย

delete from test where rowid not in (

select min(rowid) from test group by a,b);

262 rows deleted.

 

— คราวนี้มาตรวจสอบกันว่าข้อมูลที่คงเหลือถูกต้องหรือไม่

select rowid,a,b from test;

ROWID                                      A          B

——————————— ———- ———-

AAAAyvAAGAAAABYAAA          1          2

AAAAyvAAGAAAABYAED          2          2

AAAAyvAAGAAAABYAEI           3          0

 

กรณีที่ต้องการลบและคงเหลือไว้เฉพาะแถวสุดท้ายที่ซ้ำสามารถใช้คำสั่งได้ดังนี้

delete from test where rowid not in (

select max(rowid) from test group by a,b);

262 rows deleted.

 

แต่เพื่อป้องกันการเกิดการซ้ำซ้อนของข้อมูลเหล่านี้ เราสามารถที่จะใช้ unique constraints หรือ primary key ช่วยได้ ปัญหาข้อมูลซ้ำซ้อนแบบนี้ก็จะไม่มีทางเกิดขึ้นให้เกิดความปวดหัวได้อีก