المحتوى

10‏/07‏/2013

طريقة حذف الصفوف المكررة في قاعدة البيانات باستخدام SQL

بسم الله , الحمد لله والصلاة والسلام على رسول الله

أولا أحمد الله الكريم أن بلغنا رمضان شهر تتنزل فيه الرحمات أسأله جل وعلى أن يرحمنا وأن يغفر لنا إنه هو التواب الرحيم.

وبعد , فخلال عملي على بعض المواقع والتطبيقات كان لزاما علي في بعض الأحيان حذف الصفوف المتكررة في قاعدة البيانات , وكان ديدني في ذلك الرجوع إلى لغة البرمجة سواء C# أو VB أو PHP , ولكن اضطرني المطاف أخيرا إلى ضرورة تنفيذ ذلك مباشرة من قاعدة البيانات دون الرجوع إلى لغة البرمجة (مرغم أخاك لابطل).

ومع العديد من المحاولات التي باءت كلها بالفشل إلا واحدة , ومع بالغ الأسف لم أستطع خلالها سوى عرض الجدول كما أريده دون أي صفوف مكررة لكنني لم أستطع حفظه.

إن تيسر لي الوقت فسأضع هنا كود الاستعلام , وقد استعملت فيه GROUP BY و NOT IN وكانا متوافقين مع SELECT إلا أنني مع استبدالها بـ DELETE كان الأمر أشبه بالمعضلة.

هذه الطريقة التي لم تفي بالغرض كانت وبعجالة تتلخص في تجهيز الجدول بدون تكرار باستخدام GROUP BY ومن ثم تنفيذ الاستعلام SELECT والاشتراط عليه بجلب كل الصفوف عدا ماتم تجهيزه بالـ GROUP BY وذلك باستخدام NOT IN

عموما استطعت عرضها كما أريد إلا أنني لم أفلح في حذفها من قاعدة البيانات.

وبعد ذلك بحث عن حل عبر شبكة الانترنت ووجدت حل للمشكلة باستخدام فكرة قريبة جدا من بعض محاولاتي إن لم أقل إنها تشبهها تماما , ولكنها كانت تحتوى على المفتاح الذي لم يكن لدي !! , وهذه هي نسخة من الاستعلام.
SELECT * FROM `get-result` LEFT OUTER JOIN ( SELECT MIN(`id`) as RowId, `my_num`, `my_desk`, `my_name`,`my_result` FROM `get-result` GROUP BY `my_num` ) as KeepRows ON `get-result`.`id= KeepRows.RowId WHERE KeepRows.RowId IS NULL
فكرته تكمن في تجهيز الجدول بدون تكرار كما بطريقتي السابقة ومن ثم دمجه مع الجدول الأصلي فيتبقى حقول فارغة في الجدول وهي تدل على أنها مكررة لأنها لم تملأ من قبل الجدول المكرر وتلك الصفوف تحذف وبذا تنتهي المشكلة.
وبما أنني أواجه مشكلة في السيرفر الخاص بي حيث امتلأ الهارد دسك الخاص بالسيرفر فكثير من الاستعلامات الخاصة بي تتوج بالتنبيه:
#3 - Error writing file '/tmp/MYLIB2XV' (Errcode: 28)
لذا كان لزاما علي أن أجد حلا آخر , ألا وهو تنفيذ الاستعلام الخاص بفلترة قاعدة البيانات باستخدام Group by ومن ثم تخزين الجدول الناتج الذي يحوي قاعدة البيانات كلها دون أي تكرار وحفظه في ملف خارجي ومن ثم حذف الجدول الحالي وأخيرا استيراد الملف الخارجي إلى داخل قاعدة البيانات.



طبعا الحل تلفيقي نوعا ما لأنه يجب أن يتم باستخدام استعلام واحد بعيدا عن الملفات الخارجية لكن ماباليد حيلة.

الاستعلام الخاص بفلترة الجدول من الصفوف المكررة وتخزين الملف المفلتر في ملف خارجي على الهارد دسك C:
SELECT `id` , `my_num` , `my_desk` , `my_name` , `my_result` INTO OUTFILE 'data.txt' FROM `get-result` GROUP BY `my_num`
والاستعلام الخاص باستيراد الملف الخارجي وتخزينه داخل قاعدة البيانات:
LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;

هذا ماتيسر لي كتابته , مع أن الأكمل كان دعم المقال بصور توضيحية لكن ماكل مايتمنى المرء يدركه , والله ولي التوفيق.

من 1 إلى 7 رمضان 1434هـ
طرابلس / ليبيا

ليست هناك تعليقات:

إرسال تعليق