IS NULL وIS NOT NULL والمساواة الآمنة مع NULL
اختبار NULL بشكل صحيح والعوامل الآمنة مع NULL حسب اللهجة
IS NULL وIS NOT NULL والمساواة الآمنة مع NULL درس مجاني في SQL Interview Prep على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في SQL Interview Prep، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.
اختبار NULL بالطريقة الصحيحة
أثبت الدرس السابق أنه لا يمكنك استخدام = للعثور على قيم NULL. فكيف تختبر وجودها فعلًا؟ باستخدام الشرطين المخصصين IS NULL وIS NOT NULL.
وهما الطريقتان الصحيحتان الوحيدتان والقابلتان للنقل بين الأنظمة للتحقق من القيم المفقودة، وسيرفض المحاورون استخدام col = NULL كلما رأوه.
يغطي هذا الدرس IS NULL وIS NOT NULL وعائلة IS DISTINCT FROM وعوامل المساواة الآمنة مع NULL الخاصة بكل لهجة SQL. وتُعد معرفة الفروق بين قواعد البيانات إشارة قوية إلى الخبرة المتقدمة.
IS NULL وIS NOT NULL
يعيد IS NULL القيمة TRUE عندما تكون القيمة NULL، وFALSE في غير ذلك. والأهم أنه لا يعيد UNKNOWN أبدًا، ولذلك يمكن استخدامه بأمان مباشرةً في WHERE.
أما IS NOT NULL فهو مكمله التام: يعيد TRUE لأي قيمة فعلية، وFALSE للقيمة NULL.
يُعد هذان الشرطان أساس التعامل مع NULL. وهما جزء من SQL القياسي، ويعملان بالطريقة نفسها في MySQL وPostgres وSQL Server وOracle وSQLite.
-- Find employees with no recorded bonus
SELECT name FROM employees WHERE bonus IS NULL;
-- Find employees that do have a bonus
SELECT name FROM employees WHERE bonus IS NOT NULL;لماذا تكون col = NULL خاطئة دائمًا
هذا فخ مضمون في المقابلات: يكتب المرشح WHERE bonus = NULL متوقعًا أن يعثر على المكافآت المفقودة. لكنه يعيد صفرًا من الصفوف.
تذكّر المنطق ثلاثي القيم: تكون bonus = NULL UNKNOWN لكل صف، بما في ذلك الصفوف التي تحتوي على NULL، لأن لا شيء يساوي قيمة غير معروفة. وتحتفظ WHERE بالنتائج TRUE فقط، لذا لا يطابق أي صف.
قد تعيد بعض قواعد البيانات، في أوضاع غير قياسية، كتابة = NULL داخليًا إلى IS NULL، لكن يجب ألا تعتمد على ذلك إطلاقًا. اكتب دائمًا IS NULL صراحةً.
-- WRONG: returns zero rows, bonus = NULL is UNKNOWN for all
SELECT name FROM employees WHERE bonus = NULL;
-- RIGHT:
SELECT name FROM employees WHERE bonus IS NULL;عدّ قيم NULL والقيم غير NULL
من المهام الشائعة للمحللين تدقيق جودة البيانات: ما مدى اكتمال العمود؟ اجمع بين IS NULL وCOUNT للإبلاغ عن القيم المفقودة.
لاحظ الفرق: يحصي COUNT(*) كل صف، بينما يحصي COUNT(bonus) المكافآت غير NULL فقط. ويساوي الفرق بينهما عدد قيم NULL، وهي حقيقة سنعود إليها في درس الدوال التجميعية.
SELECT
COUNT(*) AS total_rows,
COUNT(bonus) AS with_bonus,
COUNT(*) - COUNT(bonus) AS missing_bonus,
SUM(CASE WHEN bonus IS NULL THEN 1 ELSE 0 END) AS missing_check
FROM employees;المشكلة التي تحلها المساواة الآمنة مع NULL
لنفترض أنك تريد مطابقة عمودين واعتبار «كونهما NULL معًا» تطابقًا. تفشل a = b العادية؛ فعندما تكون القيمتان NULL تكون النتيجة UNKNOWN، ولذلك يُستبعد الزوج رغم أنهما «متساويان» intuitively.
يظهر هذا عند مقارنة صف قديم بصف جديد لاكتشاف التغييرات، أو عند الربط باستخدام أعمدة اختيارية. أنت بحاجة إلى مقارنة تكون فيها مقارنة NULL بـ NULL تعطي TRUE ومقارنة NULL بقيمة تعطي FALSE. وهذا ما توفره المساواة الآمنة مع NULL.
-- Goal: change-detection where two NULLs count as equal
-- Plain equality fails when both sides are NULL:
-- NULL = NULL -> UNKNOWN (treated as not-equal)
SELECT * FROM old_t o JOIN new_t n ON o.id = n.id
WHERE o.note = n.note; -- misses rows where both notes are NULLIS DISTINCT FROM (SQL القياسي)
المقارنة القياسية الآمنة مع NULL وفق معيار ANSI هي IS DISTINCT FROM وعكسها IS NOT DISTINCT FROM. وهي مدعومة في Postgres وSQL Server (الإصدار 2022 فأحدث) وغيرهما.
- تعني
a IS NOT DISTINCT FROM b«متساويان، مع اعتبار NULL = NULL تساويًا». - تعني
a IS DISTINCT FROM b«مختلفان، مع التعامل مع NULL كقيمة عادية».
يعيد هذان الشرطان دائمًا TRUE أو FALSE، ولا يعيدان UNKNOWN أبدًا، ولذلك فهما آمنان في أي موضع يُتوقع فيه شرط.
-- TRUE when notes match, including both NULL
SELECT * FROM old_t o JOIN new_t n ON o.id = n.id
WHERE o.note IS NOT DISTINCT FROM n.note;
-- TRUE when notes differ (NULL vs value counts as different)
SELECT * FROM old_t o JOIN new_t n ON o.id = n.id
WHERE o.note IS DISTINCT FROM n.note;عامل <=> في MySQL
يوفر MySQL عامل مساواة مختصرًا وآمنًا مع NULL، ويُكتب كالتالي: <=>، ويُعرف باسم spaceship operator.
يعيد a <=> b القيمة 1 (TRUE) عندما يكون الطرفان متساويين أو يكونان NULL معًا، ويعيد 0 (FALSE) في غير ذلك. وهو المكافئ في MySQL للعامل IS NOT DISTINCT FROM.
إذا طلب منك المحاور مطابقة آمنة مع NULL في MySQL تحديدًا، فهذه هي الإجابة الاصطلاحية.
-- MySQL: 1 when both equal or both NULL
SELECT (NULL <=> NULL) AS both_null, -- 1
(NULL <=> 5) AS null_vs_val, -- 0
(5 <=> 5) AS val_eq; -- 1
SELECT * FROM old_t o JOIN new_t n ON o.id = n.id
WHERE o.note <=> n.note;مرجع سريع بين لهجات SQL
يقدّر القائمون بالمقابلات المرشحين الذين يعرفون حدود قابلية النقل بين اللهجات. إليكم خريطة المساواة الآمنة مع NULL:
- ANSI / Postgres / SQL Server 2022+:
IS NOT DISTINCT FROM - MySQL / MariaDB:
<=> - SQLite: يعمل
ISوIS NOTللمساواة الآمنة مع NULL - Oracle: لا يوجد عامل أصلي؛ يمكن محاكاته باستخدام
DECODE(a, b, 1, 0) = 1أو حيل COALESCE
عند عدم التأكد من محرك قاعدة البيانات، استخدموا الصيغة اليدوية القابلة للنقل المعروضة بعد ذلك.
-- SQLite NULL-safe equality
SELECT * FROM t WHERE a IS b; -- TRUE when both NULL
SELECT * FROM t WHERE a IS NOT b; -- complementمطابقة يدوية قابلة للنقل وآمنة مع NULL
عندما لا يتوفر عامل أصلي، يمكنكم إنشاء مساواة آمنة مع NULL باستخدام العناصر الأساسية. يجمع النمط القابل للنقل بين مساواة عادية وشرط صريح ينص على أن القيمتين NULL.
اقرؤوا ذلك هكذا: «القيمتان متساويتان، أو كلتاهما مفقودتان». يعمل هذا النمط مع كل قواعد البيانات، ولذلك فهو إجابة ممتازة عندما لا يحدد القائم بالمقابلة لهجة معينة.
SELECT *
FROM old_t o JOIN new_t n ON o.id = n.id
WHERE (o.note = n.note)
OR (o.note IS NULL AND n.note IS NULL);
-- Alternative using COALESCE with a sentinel that
-- cannot occur in real data:
-- WHERE COALESCE(o.note, '##NULL##') = COALESCE(n.note, '##NULL##')مثال أعمق: مفاتيح JOIN آمنة مع NULL
إليكم حالة واقعية مربكة: إجراء JOIN باستخدام مفتاح يمكن أن تكون قيمته NULL. إذا كان من الممكن أن تكون region بقيمة NULL في كلا الجانبين، فإن equi-join العادي يستبعد تلك الأزواج بصمت، لأن NULL = NULL نتيجته UNKNOWN.
إذا كانت قاعدة العمل تنص على أن «الصفوف التي لا تحتوي على منطقة يجب أن تطابق الصفوف الأخرى التي لا تحتوي على منطقة»، فيجب جعل شرط JOIN آمنًا مع NULL. اذكروا هذا الافتراض صراحةً في المقابلة، ثم اختاروا العامل المتوافق مع محرك قاعدة البيانات.
-- Postgres / ANSI: match including both-NULL regions
SELECT a.id, b.id
FROM table_a a
JOIN table_b b
ON a.region IS NOT DISTINCT FROM b.region;
-- MySQL equivalent: ON a.region <=> b.regionنقاط مهمة للمقابلة
للتعامل مع أي سؤال عن اختبار NULL بوضوح:
- استخدموا دائمًا
IS NULL/IS NOT NULL؛ ولا تستخدموا مطلقًا= NULL. - لا تُرجع هذه الشروط سوى TRUE أو FALSE، ولذلك فهي آمنة في WHERE.
- لمطابقة «NULL يساوي NULL»، استخدموا IS NOT DISTINCT FROM وفق معيار ANSI، أو <=> في MySQL.
- اذكروا اللهجة التي تستهدفونها؛ وعند عدم التأكد، اطرحوا البديل القابل للنقل باستخدام شرط OR.
إن تسمية العامل القياسي وعامل المورّد معًا تُظهر اتساع معرفتكم، وهو ما يلاحظه مسؤولو الفرز.
اختبار سريع
اختاروا المقارنة الصحيحة الآمنة مع NULL.
مراجعة
يمكنكم الآن اختبار NULL بطريقة صحيحة:
IS NULL/IS NOT NULLهما الاختباران الصحيحان الوحيدان والقابلان للنقل لـ NULL؛ ولا يُرجعان UNKNOWN مطلقًا.- يُرجع
col = NULLدائمًا صفر صفوف؛ وهو من الحيل الشائعة في المقابلات. - تتعامل المساواة الآمنة مع NULL مع قيمتي NULL على أنهما متساويتان: IS NOT DISTINCT FROM في ANSI/Postgres، و<=> في MySQL، وIS في SQLite.
- عند عدم وجود عامل مناسب، استخدموا
(a = b) OR (a IS NULL AND b IS NULL).
التالي: استبدال NULL بقيم افتراضية باستخدام COALESCE وNULLIF ودوال المورّد مثل ISNULL.
الأسئلة الشائعة
هل درس «IS NULL وIS NOT NULL والمساواة الآمنة مع NULL» مجاني؟
نعم — نص درس «IS NULL وIS NOT NULL والمساواة الآمنة مع NULL» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة SQL Interview Prep، انتقل إلى CoddyKit PRO. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.
ماذا ستتعلم في «IS NULL وIS NOT NULL والمساواة الآمنة مع NULL»؟
اختبار NULL بشكل صحيح والعوامل الآمنة مع NULL حسب اللهجة تتمرن على SQL Interview Prep مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ SQL Interview Prep؟
لا تُشترط خبرة سابقة. SQL Interview Prep على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «IS NULL وIS NOT NULL والمساواة الآمنة مع NULL»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس SQL Interview Prep هذا؟
نعم. كل درس في SQL Interview Prep يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- المنطق ثلاثي القيم وUNKNOWN
- IS NULL وIS NOT NULL والمساواة الآمنة مع NULL
- COALESCE وNULLIF وISNULL
- قيم NULL في التجميعات وعمليات الربط وDISTINCT