الانتقال إلى المحتوى الرئيسي
الوحدة 4 · الدرس 2 من 414/57 في الدورة~10 min
دروس الوحدة (2/4)

التعامل مع القيم الخالية: IS NULL و COALESCE

في مجموعة البيانات employees، يعتبر أندريا كوستا شخصًا مميزًا: لقد فعل ذلك محمي_INLINE_1. لقد قمت بالفعل بالتعامل مع NULL (مع LEFT JOIN)، ولكن حان الوقت لأخذ الأمر على محمل الجد: NULLs في SQL تتصرف بشكل مختلف عن أي قيمة أخرى، وتجاهلها هو أحد السلوكيات أهم أسباب الأخطاء في كود الإنتاج.

NULL ليس صفراً، وليس سلسلة فارغة

NULL يعني قيمة غير معروفة/مفقودة. إنه ليس محمي_INLINE_6، وليس محمي_INLINE_7، وليس محمي_INLINE_8. إنه "لا أعرف". ومن هنا تأتي خاصية مدهشة: NULL لا يساوي شيئًا، ولا حتى نفسه.

SQL
-- All these expressions return NULL (not true!):
SELECT NULL = NULL;       -- NULL
SELECT NULL = 0;          -- NULL
SELECT NULL <> 'qualcosa'; -- NULL

النتيجة الملموسة: WHERE column = NULL لا تعمل أبدًا. يجب عليك استخدام المشغلون المخصصون IS NULL / IS NOT NULL:

SQL
-- Employees without a department:
SELECT first_name, last_name
FROM   employees
WHERE  department_id IS NULL;

-- Employees WITH a department:
SELECT first_name, last_name
FROM   employees
WHERE  department_id IS NOT NULL;

COALESCE - التراجع الفارغ

غالبًا ما تريد عرض شيء ما بدلاً من NULL عندما تكون البيانات مفقود: السلسلة '(none)'، صفر، التاريخ الافتراضي. الوظيفة التي يفعل هذا بالضبط COALESCE(a, b, c, ...): فهو يُرجع **الأول وسيطة غير فارغة ** في القائمة.

SQL
-- Show the department_id, or 0 if missing:
SELECT first_name, last_name, COALESCE(department_id, 0) AS dept
FROM   employees;

عند دمجه مع LEFT JOIN يصبح قويًا بشكل لا يصدق بالنسبة للتقارير:

SQL
SELECT e.first_name,
       e.last_name,
       COALESCE(d.name, '(nessun dipartimento)') AS dipartimento
FROM   employees   AS e
LEFT JOIN departments AS d ON e.department_id = d.id;

النتيجة: إرجاع جميع الموظفين مع اسم القسم أو صريح التسمية لأولئك الذين ليس لديهم واحدة.

فارغة والمجاميع

الوظائف المجمعة تجاهل NULLs (باستثناء COUNT(*)):

  • COUNT(department_id) يحسب فقط الصفوف ذات القيمة؛
  • AVG(salary) المتوسطات التي تتجاهل NULLs — لا تعاملها على أنها 0؛
  • SUM(...) يجمع القيم غير الفارغة فقط.

هذا هو ما تريده دائمًا تقريبًا. ولكن من الجيد أن تعرف: إذا كنت كذلك ابحث عن "إجمالي عدد الموظفين" استخدم COUNT(*)، وليس محمي_INLINE_37.

جربه

تمرين#sql.m4.l2.e1
المحاولات: 0جارٍ التحميل…

بالنسبة لكل موظف، اعرض الاسم الأول (الاسم_الأول) واسم العائلة (اسم_العائلة) والعمود "dipartimento_id" الذي يساوي معرف_القسم الخاص بهم أو -1 إذا لم يتم تعيينه. ثلاثة أعمدة، صف واحد لكل موظف.

جارٍ تحميل المحرر…
إظهار التلميح

استخدم COALESCE(department_id, -1) لاستبدال القيم الخالية بـ -1.

الحل متاح بعد 3 من المحاولات

تمرين المراجعة

تمرين#sql.m4.l2.e2
المحاولات: 0جارٍ التحميل…

قم بإرجاع الاسم الأول (first_name)، والاسم الأخير (last_name) واسم القسم (departments.name) لجميع الموظفين، مع إظهار '(nessuno)' عندما يكون القسم مفقودًا. استخدم LEFT JOIN + COALESCE.

جارٍ تحميل المحرر…
إظهار التلميح

يعالج COALESCE(d.name, '(nessuno)') القيمة NULL المقدمة بواسطة LEFT JOIN.

الحل متاح بعد 3 من المحاولات