يمكن بناء 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 من الأساسيات للاحتراف.