كيف نسترجع الصفوف المكررة عندما يحتوي مفتاح التكرار على NULL؟

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

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

الإجابة

يمكن بناء CTE تسرد مفاتيح المجموعات التي تظهر أكثر من مرة، ثم ربطها بالجدول الأصلي لاسترجاع تفاصيل جميع الصفوف المكررة. تظهر مشكلة دقيقة إذا كان مفتاح التكرار يقبل NULL، وكانت قواعد السؤال تعد الصفوف ذات القيمة الفارغة مجموعة واحدة.

يجمع GROUP BY هذه الصفوف معًا، لكن المقارنة العادية باستخدام علامة المساواة لا تجعل NULL مساوية لـ NULL. لذلك قد تتعرف مرحلة التجميع على مجموعة مكررة، ثم يفشل الربط العادي في إرجاع تفاصيلها. في MySQL يوفر العامل <=> مقارنة مساواة آمنة مع القيم الفارغة.

مثال

WITH customers AS (
  SELECT 1 AS id, CAST(NULL AS CHAR(100)) AS email
  UNION ALL SELECT 2, NULL
  UNION ALL SELECT 3, 'a@example.com'
), duplicate_emails AS (
  SELECT email
  FROM customers
  GROUP BY email
  HAVING COUNT(*) > 1
)
SELECT c.id, c.email
FROM customers AS c
JOIN duplicate_emails AS d ON c.email <=> d.email
ORDER BY c.id;

نستخدم COUNT(*) كي يشمل العد الصفوف ذات البريد الفارغ. أما COUNT(email) فلا يعدها. هذا الحل يعرض جميع صفوف المجموعات المكررة، وليس النسخ الزائدة بعد استبعاد سجل واحد من كل مجموعة.

باختصار: إذا كانت NULL جزءًا من تعريف التكرار، استخدم عد الصفوف ومقارنة آمنة معها عند ربط النتائج.

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

اختبر فهمك

نعد كل قيم email الفارغة مجموعة واحدة. أي شرط ربط يسترجع أيضًا تفاصيل هذه المجموعة إذا كانت مكررة؟

WITH customers AS (
  SELECT 1 AS id, CAST(NULL AS CHAR(100)) AS email
  UNION ALL SELECT 2, NULL
  UNION ALL SELECT 3, 'a@example.com'
), duplicate_emails AS (
  SELECT email
  FROM customers
  GROUP BY email
  HAVING COUNT(*) > 1
)
SELECT c.id, c.email
FROM customers AS c
JOIN duplicate_emails AS d
/* Add the ON clause here. */;