كيف نحدد النسخ الزائدة من السجلات المكررة باستخدام ROW_NUMBER؟

متوسطقراءة دقيقةآخر تحديث 3 أكتوبر 2026

SQL قواعد البيانات

الإجابة

عند مراجعة التكرارات يجب التمييز بين عرض جميع صفوف المجموعة المكررة وعرض النسخ الزائدة فقط. إذا ظهر البريد الإلكتروني ثلاث مرات ونريد الاحتفاظ بسجل واحد، فعدد النسخ الزائدة هو اثنان. تساعد ROW_NUMBER() على تحديد السجل المحتفظ به وبقية النسخ بوضوح.

نقسم العملاء بحسب البريد الإلكتروني، ثم نرتب كل مجموعة بحسب المعرّف تصاعديًا. يحصل أصغر معرّف على الرقم واحد، وتحصل السجلات الأخرى على أرقام أكبر. نضع الحساب في CTE ونختار الأرقام الأكبر من واحد لعرض النسخ المرشحة للمراجعة دون تعديل البيانات الأصلية.

مثال

WITH customers AS (
  SELECT 1 AS id, 'a@example.com' AS email
  UNION ALL SELECT 2, 'a@example.com'
  UNION ALL SELECT 3, 'b@example.com'
), numbered AS (
  SELECT id, email,
         ROW_NUMBER() OVER (
           PARTITION BY email ORDER BY id
         ) AS rn
  FROM customers
)
SELECT id, email
FROM numbered
WHERE rn > 1
ORDER BY id;

تعتمد صحة الحل على تعريف التكرار المطلوب. إذا كان التكرار يعني تطابق البريد والاسم معًا، فيجب وضع العمودين داخل التقسيم. كما أن الاختيار بحسب المعرّف لا يعني بالضرورة الاحتفاظ بالسجل الأحدث؛ هذا قرار يجب أن يعكس قاعدة العمل.

باختصار: اجعل السجل المحتفظ به رقم واحد، ثم اختر rn > 1 لعرض النسخ الزائدة فقط.

هل تريد تعلّم SQL خطوة بخطوة مع تمارين عملية؟ تابع مسار SQL من الأساسيات للاحتراف.

اختبر فهمك

نريد عرض النسخ الزائدة فقط مع الاحتفاظ بأصغر id لكل email. أي شرط نضيفه إلى الاستعلام الخارجي؟

WITH customers AS (
  SELECT 1 AS id, 'a@example.com' AS email
  UNION ALL SELECT 2, 'a@example.com'
  UNION ALL SELECT 3, 'a@example.com'
  UNION ALL SELECT 4, 'b@example.com'
), numbered AS (
  SELECT id, email,
         ROW_NUMBER() OVER (
           PARTITION BY email ORDER BY id
         ) AS rn
  FROM customers
)
SELECT id, email
FROM numbered
/* Add the WHERE clause here. */;