تعتبر معالجة البيانات وإدارتها بكفاءة حجر الزاوية في التحليل الإحصائي المتقدم وعلوم البيانات المعاصرة. وضمن بيئة نظام التحليل الإحصائي SAS (Statistical Analysis System)، تمثل لغة الاستعلام الهيكلية المنفذة عبر إجراء الاستعلام الهيكلي (PROC SQL) إحدى أقوى الركائز البرمجية التي تمنح المطورين والمحللين القدرة على التفاعل مع مجموعات البيانات الكبيرة والمعقدة بمرونة فائقة. يوفر هذا الإجراء جسراً متيناً يربط بين فلسفة المعالجة الجدولية المألوفة في خطوة البيانات (DATA Step) والمعايير العلائقية الدولية المعتمدة من المعهد الأمريكي للمعايير القومية (ANSI SQL). ومن بين العمليات العلائقية المتقدمة التي يتيحها هذا الإجراء، تبرز عمليات المجموعات بوصفها أدوات رياضية أساسية لمعالجة السجلات وتصفيتها بناءً على معايير المنطق المجموعي.
يحتل مشغل الاستثناء (EXCEPT) مكانة فريدة ضمن عائلة مشغلات المجموعات في بيئة PROC SQL؛ إذ يوفر وسيلة رياضية قطعية لاستخراج الملاحظات والسجلات الموجودة في مجموعة بيانات محددة والتي لا وجود لها على الإطلاق في مجموعة بيانات أخرى. لا يقتصر دور هذا المشغل على مجرد التصفية السطحية، بل يمتد ليشكل أداة تدقيق وتحقق بالغة الأهمية في مجالات شديدة الحساسية، مثل التجارب السريرية للأدوية، والتحليلات المالية والمصرفية، والدراسات الوبائية، ومطابقة البيانات الضخمة. إن الفهم العميق لكيفية عمل مشغل EXCEPT، وتفاصيل أدائه الداخلي، وتفاعله مع الذاكرة، يمثل فارقاً جوهرياً بين استعلامات بطيئة تستهلك موارد المعالجة واستعلامات عالية الكفاءة والدقة تلبي متطلبات المشاريع المؤسسية الضخمة.
تهدف هذه الدراسة المعمقة والموسعة إلى تقديم دليل مرجعي شامل ومتكامل حول استخدام مشغل الاستثناء EXCEPT ضمن إجراء PROC SQL في نظام ساس. سنستعرض عبر هذا البحث الأسس النظرية المستمدة من نظرية المجموعات والجبر العلائقي، والقواعد النحوية الصارمة التي تحكم بناء الاستعلام، مع تقديم دراسات حالة تطبيقية واقعية تعكس التحديات اليومية التي تواجه مبرمجي ساس. كما تتناول المقالة تحليلاً مقارناً بين EXCEPT والبدائل البرمجية الشائعة مثل الربط الخارجي الأيسر (LEFT JOIN) وخطوة دمج البيانات التقليدية (DATA Step MERGE)، مسلطين الضوء على أفضل ممارسات تحسين الأداء وإدارة الذاكرة، ومعالجة القيم المفقودة، واستكشاف الأخطاء وتصحيحها وفق أحدث المعايير العلمية والمهنية.
- 1. مقدمة إلى مشغل الاستثناء (EXCEPT) في لغة الاستعلام الهيكلية داخل ساس (PROC SQL)
- 2. البنية النحوية الأساسية وتكوين جملة EXCEPT في PROC SQL
- 3. المنطق الرياضي ونظرية المجموعات وراء عملية الفرق (Set Difference)
- 4. دراسة حالة تطبيقية: مقارنة مجموعات بيانات اللاعبين باستخدام EXCEPT
- 5. المقارنة المعمقة بين مشغلي EXCEPT و EXCEPT ALL في ساس
- 6. الفروق التقنية بين مشغل EXCEPT والربط الخارجي الأيسر (LEFT JOIN)
- 7. التعامل مع القيم المفقودة (Missing Values) وتطابق البيانات
- 8. تحسين الأداء وإدارة الذاكرة عند تطبيق EXCEPT على قواعد البيانات الضخمة
- 9. مقارنة مشغل EXCEPT في PROC SQL مع أسلوب خطوة البيانات (DATA Step MERGE)
- 10. الأخطاء الشائعة واستكشاف المشكلات وإصلاحها عند استخدام EXCEPT
- 11. تطبيقات متقدمة: استخدام EXCEPT مع المجموعات الفرعية والتصفية المعقدة
- 12. أفضل الممارسات المنهجية لتوثيق وضمان جودة استعلامات EXCEPT
- خاتمة
- المراجع
1. مقدمة إلى مشغل الاستثناء (EXCEPT) في لغة الاستعلام الهيكلية داخل ساس (PROC SQL)
1.1 المفهوم النظري لعمليات المجموعات في بيئة ساس
تستند نظم إدارة قواعد البيانات العلائقية الحديثة في جوهرها إلى نظرية المجموعات (Set Theory) التي صاغها عالم الرياضيات جورج كانتور، والتي طورها إدغار كود لاحقاً لتأسيس الجبر العلائقي (Relational Algebra). في هذا الإطار الرياضي، لا يُنظر إلى الجداول وقواعد البيانات بوصفها مجرد ملفات مسطحة تحتوي على صفوف وأعمدة متراصة، بل يتم التعامل مع كل جدول أو استعلام كمجموعة رياضية تتكون من عناصر فريدة تُعرف بالسجلات أو الصفوف (Tuples). وتتيح عمليات المجموعات في الجبر العلائقي دمج هذه الكيانات الرياضية أو تفكيكها أو مقارنتها استناداً إلى براهين رياضية قطعية، مما يضمن اتساق البيانات وعدم تناقضها أثناء المعالجة والتحليل.
تعتبر عملية الفرق المجموعي (Set Difference)، التي يمثلها مشغل EXCEPT، الركيزة الثالثة في الثالوث المجموعي الأساسي الذي يضم أيضاً الاتحاد (UNION) والتقاطع (INTERSECT). تتمثل وظيفة عملية الفرق في استبعاد التقاطعات البيانية بين مجموعتين محددتين، بحيث تعيد كافة السجلات التي تنتمي حصرياً إلى المجموعة المرجعية الأولى دون أن يكون لها أي أثر أو نظير في المجموعة الثانية المقارنة. ويتميز إجراء PROC SQL داخل نظام ساس بقدرته الفائقة على تنفيذ هذه العمليات الجبرية المعقدة بسلاسة تامة، حيث يدمج محرك ساس المترجم الداخلي للغة SQL القياسية مع محركات التخزين فائقة السرعة التابعة لساس، مما يتيح للمحللين إجراء عمليات الفرق المجموعي على ملايين السجلات في فترات زمنية وجيزة.
يختلف نطاق استخدام مشغل الاستثناء بصورة جوهرية عن العمليات التكاملية الأخرى. فبينما يهدف مشغل الاتحاد (UNION) إلى تجميع ودمج الرؤى والبيانات من مصادر متعددة لإنشاء مجموعة شاملة تضم جميع العناصر، ويهدف مشغل التقاطع (INTERSECT) إلى رصد وتحديد القواسم المشتركة والسجلات المتطابقة في جميع الجداول محل الدراسة، فإن مشغل الاستثناء (EXCEPT) يركز حصرياً على رصد “التنافر” و”التباين” و”الغياب”. هذا التركيز الانتقائي يجعل من مشغل الاستثناء أداة فريدة لا غنى عنها في تحديد الفروقات التحليلية الدقيقة، وعزل البيانات الشاذة، وتحديد السجلات المنفردة التي تستوجب فحصاً استقصائياً متخصصاً.
1.2 سياق استخدام مشغل EXCEPT في معالجة البيانات الإحصائية
في بيئات العمل الإحصائي والتحليلي المتقدمة، لا تقتصر التحديات على استخراج البيانات المتاحة فحسب، بل تمتد لتشمل التدقيق المعقد في البيانات غير المكتملة أو المتضاربة. تنشأ الحاجة إلى مشغل EXCEPT في سيناريوهات واقعية متعددة، مثل التحقق من مطابقة السجلات في قواعد بيانات الرعاية الصحية، حيث يتعين على المحلل تحديد قائمة المرضى الذين تم تسجيلهم في المرحلة السريرية الأولى وتخلفوا عن الحضور في المرحلة السريرية الثانية. يوفر مشغل الاستثناء هنا حلاً برمجياً مباشراً لاستخراج هؤلاء الأفراد بدقة مطلقة دون الحاجة إلى كتابة خوارزميات فحص شرطية معقدة ومتعددة المراحل.
كذلك تبرز أهمية المشغل في تصميم التجارب الإحصائية وعزل العينات الضابطة؛ إذ يتطلب التحليل التجريبي الرصين استبعاد الملاحظات الخاضعة لمتغيرات دخيلة أو ظروف تجريبية متداخلة. ومن خلال صياغة استعلام يعتمد على EXCEPT، يمكن للباحث طرح مجموعة الملاحظات المشوبة بالتدخلات التجريبية من العينة الإجمالية، مما يضمن بقاء العينات النقية فقط التي تحقق الفرضيات الإحصائية الصارمة. يسهم هذا النهج في حماية التحليلات اللاحقة، مثل نماذج الانحدار الخطي وتحليل التباين، من الانحيازات الناتجة عن البيانات الملوثة أو المتداخلة دون وجه حق.
علاوة على ذلك، يمثل مشغل الاستثناء حجر الزاوية في عمليات ضمان جودة وتكامل البيانات (Data Integrity and Quality Assurance) وتدقيق مسارات استخراج وتحويل وتحميل البيانات (ETL). في مستودعات البيانات المؤسسية الكبرى، يستخدم مهندسو البيانات مشغل EXCEPT لاكتشاف السجلات المفقودة بين الجداول التشغيلية اليومية وجداول الأرشفة التاريخية، ومراجعة اتساق المفاتيح الرئيسية والأجنبية. ويؤدي استخدام هذا المشغل إلى تقليص التعقيد البرمجي بصورة لافتة للنظر، حيث يستغني المبرمج عن الاستعلامات الفرعية المتداخلة (Correlated Subqueries) والشروط المنطقية الملتوية، مما ينعكس إيجاباً على مقروئية الشفرة البرمجية، ويسهل مراجعتها والتحقق منها وصيانتها على المدى الطويل.
2. البنية النحوية الأساسية وتكوين جملة EXCEPT في PROC SQL
2.1 الصيغة العامة للتعليمة البرمجية وقواعد الصياغة
يتطلب استخدام مشغل الاستثناء داخل إجراء PROC SQL الالتزام ببنية نحوية محددة تحكمها قواعد معيارية صارمة مستمدة من معايير لغة الاستعلام الهيكلية. تتكون الجملة الاستعلامية في أبسط صورها من شطرين أساسيين يربط بينهما المشغل الرياضي، حيث يبدأ الاستعلام بعبارة الاختيار الأولى، متبوعة بكلمة EXCEPT، ثم عبارة الاختيار الثانية، وتنتهي الكتلة البرمجية بالكامل بفاصلة منقوطة تتبعها تعليمة الإنهاء QUIT. إن التركيب العام يتبع النموذج القياسي الآتي من الناحية البنائية: استعلام استرجاع للجدول الأول يليه مشغل الاستثناء ثم استعلام استرجاع للجدول الثاني.
يعمل محرك التحليل النحوي في ساس على تفسير هذه البنية بترتيب منطقي دقيق يختلف عن ترتيب الكتابة الظاهري. يقوم المحرك أولاً بتقييم الاستعلام الأول وتحديد كافة السجلات المطابقة لمعاييره، ثم ينتقل لتقييم الاستعلام الثاني بشكل مستقل تماماً لتشكيل مجموعة المقارنة. بعد تجهيز هاتين المجموعتين المؤقتتين في مساحة الذاكرة المخصصة، يشرع المحرك في تطبيق خوارزمية الاستبعاد المجموعي، حيث يمر على سجلات المجموعة الأولى ويفحص وجودها في المجموعة الثانية؛ فإذا تطابق السجل في جميع قيمه يتم استبعاده نهائياً، وإن لم يجد له نظيراً يتم تضمينه في جدول المخرجات النهائي.
من الأهمية بمكان التأكيد على أن إجراء PROC SQL في ساس هو إجراء تفاعلي وتراكمي (Interactive Procedure). وهذا يعني أنه لا ينتهي تلقائياً بمجرد الوصول إلى نهاية عبارة SELECT المنتهية بفاصلة منقوطة، بل يظل الإجراء مفتوحاً ومحتجزاً لموارد المعالجة في بيئة ساس حتى يتلقى صراحة تعليمة QUIT أو تعليمة RUN جديدة تبدأ خطوة أخرى. لذلك، يجب على المبرمج الحريص دائماً إنهاء كتل استعلامات PROC SQL بتعليمة QUIT لضمان تحرير مساحة الذاكرة، وإغلاق المؤشرات على الجداول المستهدفة، وتسجيل إحصاءات وقت التنفيذ في سجل تشغيل ساس بطريقة صحيحة ودقيقة.
2.2 الاشتراطات المعيارية للأعمدة والبيانات المدخلة
تفرض عمليات المجموعات في لغة SQL قيوداً صارمة تتعلق بتوافق المجموعات (Set Union-Compatibility)، وهي شروط رياضية وهندسية لا يمكن تجاوزها لضمان صحة تنفيذ مشغل EXCEPT. الشرط الأول والأساسي هو التطابق العددي المطلق للأعمدة المسترجعة بين كلا شطري الاستعلام. إذا احتوى شطر الاستعلام الأول على ثلاثة أعمدة، فيجب حتماً أن يحتوي شطر الاستعلام الثاني على ثلاثة أعمدة أيضاً. يؤدي أي خلل في هذا التوازن العددي إلى توقف محرك ساس فوراً وإصدار خطأ تركيبي في سجل التشغيل يوضح عدم توافق الأعمدة المحددة للعملية.
الشرط المعياري الثاني يكمن في توافق أنواع المتغيرات عبر الأعمدة المتقابلة وفق تسلسلها الترتيبي. يجب أن يتوافق نوع البيانات للمتغير الأول في الاستعلام الأول مع نوع البيانات للمتغير الأول في الاستعلام الثاني (كلاهما رقمي Numeric أو كلاهما نصي Character)، ويتكرر هذا الالتزام الحرفي مع المتغير الثاني والثالث وهكذا. من الجدير بالذكر أن محرك PROC SQL في ساس لا يفرض تطابق أسماء الأعمدة بين الجدولين؛ فالاسم المعروض في الجدول الناتج سيتم اشتقاقه افتراضياً من أسماء أعمدة الاستعلام الأول، ولكن الأهمية القصوى تنصب على تطابق نوع البيانات وملاءمة النطاق التخزيني لتفادي أخطاء عدم توافق الأنواع (Type Mismatch).
إضافة إلى ذلك، يلعب ترتيب الأعمدة في عبارة SELECT دوراً جوهرياً في تحديد النتيجة المنطقية للفرز والاستثناء، وليس مجرد مظهر عرض البيانات. نظراً لأن المقارنة المجموعية تتم عموداً بعمود وفقاً لموقع المتغير في القائمة المسترجعة، فإن وضع عمود رقمي يمثل “معرّف المريض” في الموقع الأول في الجدول الأول، ووضع عمود رقمي يمثل “عمر المريض” في الموقع الأول في الجدول الثاني سيجعل الاستعلام يمر برمجياً دون أخطاء نحوية نظراً لتطابق النوع الرقمي، ولكنه سينتج كارثة منطقية في البيانات المسترجعة، حيث سيقارن المحرك المعرّفات بالأعمار. ولهذا يتعين على المطور توخي الحذر الشديد وضمان التطابق الدلالي والترتيبي الدقيق لكافة المتغيرات المدرجة في كلا الاستعلامين.
3. المنطق الرياضي ونظرية المجموعات وراء عملية الفرق (Set Difference)
3.1 التمثيل الرياضي لعملية الطرح المجموعي (A B)
في لغة الرياضيات البحتة وجبر المجموعات، يُعبر عن عملية الفرق بين مجموعتين رماديتين بالصيغة الرياضية A B أو A – B. وتُعرف هذه العملية منطقياً بأنها مجموعة كل العناصر x التي تحقق الشرط الرياضي المزدوج: x ينتمي إلى المجموعة A و x لا ينتمي إلى المجموعة B. عند ترجمة هذه المعادلة الرياضية إلى سياق نظم قواعد البيانات، تمثل المجموعة A الجدول المرجعي الأول المذكور قبل المشغل، بينما تمثل المجموعة B الجدول الثاني المذكور بعده، ويكون الناتج عبارة عن فضاء بياني جديد يحتوي حصراً على السجلات الخاصة بالجدول A الخالية من أي اشتراك مع B.
من أهم الخصائص الجبرية التي يجب استيعابها في هذا الصدد هي خاصية “عدم التبادلية” (Non-Commutative Property). في العمليات الحسابية البسيطة مثل الجمع أو الضرب، أو في العمليات المجموعية التناظرية مثل الاتحاد (A ∪ B = B ∪ A) والتقاطع (A ∩ B = B ∩ A)، تكون النتيجة واحدة بغض النظر عن ترتيب الأطراف. أما في عملية الفرق المجموعي ومشغل EXCEPT، فإن (A EXCEPT B) لا تساوي بأي حال من الأحوال (B EXCEPT A)، إلا في حالة تطابق المجموعتين تماماً حيث يكون الناتج مجموعة خالية في الحالتين. إن تغيير موضع الجداول يغير جذرياً المعنى الدلالي للسؤال التحليلي المطروح على قاعدة البيانات.

تساعد مخططات فن (Venn Diagrams) بشكل استثنائي في توضيح وتصوير هذا السلوك المنطقي. إذا مثلنا الجدول الأول بدائرة A والجدول الثاني بدائرة متقاطعة معها B، فإن ناتج مشغل EXCEPT يقتصر تماماً على الهلال الخارجي للدائرة A المستبعد منه مساحة التقاطع المشتركة بين الدائرتين، مع تجاهل الهلال الخاص بالدائرة B كلياً. تتطلب عملية الاستبعاد هذه تطابقاً كلياً وشاملاً لجميع قيم السجل؛ فإذا كان السجل يمتلك خمسة حقول، وتطابقت أربعة منها بين الجدولين واختلف حقل واحد فقط، فإن السجل يُعتبر مختلفاً رياضياً ويبقى ضمن مخرجات الجدول الأول ولا يتم استبعاده.
3.2 إزالة التكرار التلقائية في مشغل EXCEPT القياسي
يتميز مشغل EXCEPT في معايير SQL ونظام ساس بسلوك افتراضي حاسم يتمثل في “إزالة التكرار التلقائية” (Implicit Deduplication). بموجب المبادئ الصارمة لنظرية المجموعات الكلاسيكية، لا يمكن للمجموعة أن تحتوي على عناصر مكررة متطابقة؛ فالعنصر إما أن ينتمي للمجموعة أو لا ينتمي إليها. وانطلاقاً من هذه الفلسفة الرياضية، عندما ينفذ محرك PROC SQL مشغل EXCEPT بصيغته القياسية، فإنه يقوم تلقائياً بدمج السجلات المكررة في الجدول الأول وتحويلها إلى سجل فريد واحد في المخرجات النهائية قبل أو أثناء عملية الطرح.
يعني هذا السلوك عملياً أنه إذا كان السجل “س” مكرراً عشر مرات في الجدول الأول A، ولم يكن له أي وجود في الجدول الثاني B، فإن المخرجات النهائية لعملية A EXCEPT B لن تحتوي على السجل “س” عشر مرات، بل ستظهره مرة واحدة فقط. يُعامل المحرك التكرارات المتطابقة كوحدة واحدة غير قابلة للتجزئة. يحقق هذا السلوك الافتراضي فائدة تحليلية كبرى عندما يكون الهدف استخراج قائمة فريدة من الكيانات أو المعرفات المستثناة، متجنباً تضخم التقارير بالبيانات الزائدة والمكررة التي قد تشوش على متخذي القرار.
ومع ذلك، ينطوي هذا الإجراء الافتراضي على تكلفة حسابية وتشغيلية ينبغي أخذها في الحسبان عند تصميم معماريات معالجة البيانات. لتنفيذ إزالة التكرار، يُجبر محرك ساس على إخضاع مجموعات البيانات لعملية فرز ضمني (Internal Sort) مستهلكة للموارد لتحديد السجلات المتماثلة وحذف الفائض منها. تتطلب هذه العملية استهلاكاً ملحوظاً لمساحة الذاكرة العشوائية (RAM) ومساحات التخزين المؤقت في مكتبة WORK، مما يستدعي من مهندسي البيانات دراسة ما إذا كان هذا الإلغاء التلقائي للازدواجية مطلوباً تحليلياً أم أنه يشكل عبئاً غير مبرر يمكن تفاديه باستخدام أدوات أخرى سنفصلها لاحقاً.
4. دراسة حالة تطبيقية: مقارنة مجموعات بيانات اللاعبين باستخدام EXCEPT
4.1 بناء وتجهيز بيانات العينة الأولى والثانية (data1 و data2)
لترسيخ المفاهيم النظرية السابقة ووضعها في سياق برمجي ملموس، سنعتمد على دراسة حالة واقعية تتعلق بمقارنة أداء لاعبي كرة السلة وإحصاءاتهم عبر مجموعتي بيانات تجريبية. سنقوم ببناء مجموعتين منفصلتين تحت الاسمين data1 و data2 باستخدام خطوة البيانات في ساس، حيث تتضمن كل مجموعة متغيرين رئيسيين: المتغير النصي team الذي يعبر عن اسم الفريق الرياضي، والمتغير الرقمي points الذي يعبر عن عدد النقاط المسجلة بواسطة اللاعبين في مباريات محددة. تم تصميم البيانات عمداً لتشمل قيماً متطابقة كلياً بين الجدولين، وقيماً تظهر في أحدهما وتغيب عن الآخر لإيضاح آلية الاستبعاد.
يتم إنشاء الجدول الأول data1 بحيث يشتمل على خمس ملاحظات تمثل فرقاً ونقاطاً متفاوتة، من بينها الفريق A بنقاط 12، والفريق A بنقاط 14، والفريق B بنقاط 15، والفريق B بنقاط 18، وأخيراً الفريق C بنقاط 22. وفي المقابل، يتم بناء الجدول الثاني data2 ليعكس حالة مقارنة زمنية أخرى، فيتضمن الفريق A بنقاط 12، والفريق A بنقاط 14 (وهي سجلات مشتركة متطابقة كلياً مع الجدول الأول)، بالإضافة إلى سجلات جديدة لم تكن موجودة مثل الفريق C بنقاط 20، والفريق D بنقاط 25، والفريق E بنقاط 30. يعكس هذا البناء بيئة تجريبية مثالية لاختبار سلوك الاستعلامات المجموعية في ساس.
قبل الشروع في الاستعلام، يوصى دائماً في بيئات التحليل الاحترافية باستخدام الإجراء PROC PRINT لعرض محتويات الجداول المدخلة والتأكد من صحة تخزين المتغيرات وأنواعها في مساحة العمل. يهدف التحليل في هذه المرحلة إلى الإجابة عن سؤال استقصائي محدد: “ما هي السجلات (الفرق والنقاط) المسجلة في الجدول الأول data1 والتي لم ينجح لاعبوها في تحقيقها أو لم تُرصد إطلاقاً في الجدول الثاني data2؟”. إن صياغة الهدف التحليلي بوضوح يمثل الخطوة الأولى لضمان كتابة استعلام PROC SQL يلبي الاحتياج الإحصائي بدقة متناهية.
4.2 تنفيذ كود PROC SQL والتحليل التفصيلي للمخرجات
لتنفيذ عملية الاستخراج المطلوبة، نكتب استعلام PROC SQL يستدعي كافة الحقول من الجدول الأول data1 ويطرح منها كافة الحقول من الجدول الثاني data2. نستخدم تعليمة العناوين TITLE لتوثيق محتوى التقرير الإحصائي بوضوح، مما يمنع اللبس عند قراءة النتائج من قبل الفرق البحثية. يبدأ الاستعلام باختيار كافة المتغيرات عبر علامة النجمة (*) من data1، متبوعة مباشرة بمشغل الاستثناء EXCEPT، ثم اختيار كافة المتغيرات من data2، وتنتهي الجملة البرمجية بالفاصلة المنقوطة، تليها تعليمة QUIT لإنهاء الإجراء.
عند تنفيذ هذه الشيفرة في بيئة ساس، يُجري المحرك مقارنة دقيقة وحرفية لكل صف من صفوف data1 بمحتويات data2. نبدأ بالسجل الأول (الفريق A مع 12 نقطة)؛ يبحث المحرك في data2 فيجد تطابقاً تاماً لنفس الفريق ونفس النقاط، وبالتالي يُستبعد هذا السجل تماماً من الظهور في النتيجة. ننتقل للسجل الثاني (الفريق A مع 14 نقطة)؛ يجد المحرك له نظيراً مطابقاً في data2، فيتم استبعاده أيضاً تأكيداً لقاعدة إقصاء التقاطعات البيانية. تستمر عملية الفحص مع بقية السجلات بدقة رياضية متناهية.
عند وصول المحرك إلى السجل الثالث (الفريق B مع 15 نقطة)، يبحث في data2 فلا يجد أي صف يجمع بين الفريق B والرقم 15؛ ولذلك يتم الاحتفاظ بهذا الصف وإدراجه في جدول النتائج. وبالمثل، يُفحص السجل الرابع (الفريق B مع 18 نقطة)، ونظراً لغيابه التام عن data2، يُدرج في جدول النتائج. أخيراً، يُفحص السجل (الفريق C مع 22 نقطة)؛ ومع أن data2 يحتوي على الفريق C، إلا أن النقاط المصاحبة له هي 20 وليست 22، وبما أن المقارنة تتطلب التطابق الكلي، فإن هذا السجل يعتبر فريداً ويُدرج في النتائج. تتلخص المخرجات النهائية فقط في ثلاثة صفوف: الفريق B بنقاط 15 و18، والفريق C بنقاط 22، مما يحقق الغرض التحليلي بنجاح تام.
4.3 عكس اتجاه الاستعلام ودراسة اختلاف النتائج
لتأكيد الطبيعة غير التبادلية لمشغل الاستثناء عملياً، نقوم بتعديل نص الاستعلام السابق ليعكس ترتيب الجداول، بحيث نجعل الاستعلام يبدأ باختيار السجلات من الجدول الثاني data2 متبوعاً بمشغل EXCEPT ثم اختيار السجلات من الجدول الأول data1. نغير عنوان التقرير ليصبح data2 EXCEPT data1 ليعكس الوجهة التحليلية الجديدة. هذا التغيير الطفيف في الصياغة يعيد تشكيل المنطق الاستعلامي بالكامل، ليصبح السؤال المطروح: “ما هي السجلات والنقاط التي تحققت في data2 ولم تظهر إطلاقاً في data1؟”.
بإجراء التحليل ذاته، يتبين أن المحرك سيتعامل مع data2 بوصفه المجموعة المرجعية المستهدفة. سيتم استبعاد السجلين الخاصين بالفريق A (12 و 14 نقطة) نظراً لورودهما المسبق في data1 كتقاطع مشترك. بعد ذلك، يفحص المحرك السجل (الفريق C مع 20 نقطة)، ونظراً لعدم وجود سجل في data1 يحمل القيمة 20 للفريق C، فإن السجل يتم تضمينه في النتيجة. تتبعه بعد ذلك السجلات الخاصة بالفريق D مع 25 نقطة، والفريق E مع 30 نقطة، حيث تدرج جميعها في جدول المخرجات لخلو الجدول الأول data1 منها تماماً.
تثبت هذه المقارنة التجريبية أن مخرجات الاستعلام المعاكس تتكون من ثلاثة صفوف مختلفة كلياً عن مخرجات الاستعلام الأول (الفريق C بنقاط 20، والفريق D بنقاط 25، والفريق E بنقاط 30). لا يوجد أي تقاطع أو تشابه بين المخرجين على الرغم من أن الجداول المدخلة هي نفسها. تبرز هذه النتيجة الأهمية القصوى للتخطيط المسبق في الدراسات الإحصائية الطولية والمقارنات الزمنية؛ حيث يتعين على المحلل تحديد الجدول الأساسي والجدول المقارن بعناية فائقة استناداً إلى المنطق الإحصائي المطلوب، محاذراً الوقوع في خطأ الترتيب الذي قد يقود إلى استنتاجات خاطئة بالكامل.
5. المقارنة المعمقة بين مشغلي EXCEPT و EXCEPT ALL في ساس
5.1 آلية عمل الكلمة المفتاحية ALL مع مشغل الاستثناء
يوفر معيار SQL داخل بيئة ساس خياراً برمجياً متقدماً يتمثل في إضافة الكلمة المفتاحية ALL إلى جانب مشغل الاستثناء ليصبح التركيب النحوي EXCEPT ALL. يُحدث هذا التعديل البسيط تحولاً جذرياً في فلسفة التعامل مع السجلات المتكررة داخل الجداول. إذا كان مشغل EXCEPT القياسي يعتمد منطق نظرية المجموعات الكلاسيكية الصارم الذي يلغي التكرار ويدمج الصفوف المتطابقة قسرياً، فإن مشغل EXCEPT ALL يعتمد نظرية المجموعات المتعددة (Multiset Theory أو Bag Theory)، حيث يُعامل كل تكرار كعنصر مستقل بذاته يمتلك وزناً عددياً يجب الحفاظ عليه في العمليات الحسابية.
تتلخص الآلية الحسابية لمشغل EXCEPT ALL في مبدأ “مطابقة التكرار التناقصي” (Cardinality-Based Matching). عند مقارنة مجموعتين، يقوم المحرك بعدّ مرات تكرار كل سجل محدد في الجدول الأول، وعدّ مرات تكرار السجل ذاته في الجدول الثاني، ثم يقوم بعملية طرح حسابي بسيط لعدد مرات الظهور. إذا ظهر السجل “ص” أربع مرات في الجدول الأول وظهر مرتين في الجدول الثاني، فإن عملية EXCEPT ALL ستعيد السجل “ص” مرتين في جدول المخرجات (4 – 2 = 2). أما إذا كان عدد مرات ظهوره في الجدول الثاني مساوياً لعدد ظهوره في الجدول الأول أو أكبر منه، فسيتم استبعاده تماماً من المخرجات ولن يظهر مطلقاً.

يترتب على هذا المنطق الرياضي فارق جوهري في كفاءة المعالجة واستهلاك موارد النظام. نظراً لأن EXCEPT ALL لا تتطلب إلغاء الازدواجية التلقائي، فإن محرك ساس لا يحتاج إلى تنفيذ فرز نهائي شامل لدمج السجلات المتشابهة في مخرجات الجدول الأول، مما يجعلها في كثير من الحالات أسرع في التنفيذ وأقل استهلاكاً للملفات المؤقتة في مكتبة WORK مقارنة بالمشغل القياسي. ومع ذلك، فإن المحرك يظل بحاجة إلى تتبع تعداد التكرارات بدقة عبر خوارزميات التجزئة أو الفرز الموضعي لضمان طرح العدد الدقيق للسجلات المشتركة بين المجموعتين.
5.2 أمثلة تطبيقية توضح التباين في المخرجات الرقمية
لتوضيح التباين العملي الشاسع بين المشغلين، نفترض سيناريو من واقع التدقيق المالي والمحاسبي، حيث لدينا جدول أول يحتوي على سجل حركة مالية متطابق (تسجيل قيد مدين بقيمة 500 ريال لحساب معين) مكرر ثلاث مرات نتيجة عمليات متتابعة، ولدينا جدول ثانٍ يتضمن نفس السجل المالي مكرراً مرة واحدة فقط نتيجة تسوية مصرفية جزئية. يمثل هذا التفاوت العددي حالة كلاسيكية تتطلب رصداً دقيقاً لعدد الحركات غير المسواة دفترياً.
إذا استخدم المحلل المالي مشغل الاستثناء القياسي (EXCEPT) في PROC SQL بين الجدولين، فإن النتيجة ستكون مفاجئة وخاطئة محاسبياً؛ حيث سيقوم المشغل أولاً بدمج السجلات الثلاثة في الجدول الأول لتصبح سجلاً واحداً فريداً، ثم يقارنه بالسجل الموجود في الجدول الثاني فيجد تطابقاً، وبالتالي يستبعد السجل تماماً وتكون النتيجة النهائية جدولا فارغاً (Zero Rows). يختفي من التقرير حركتان ماليتان بقيمة إجمالية قدرها 1000 ريال كان ينبغي التدقيق فيهما، وذلك بسبب سلوك الإلغاء التلقائي للازدواجية المدمج في المشغل القياسي.
في المقابل، إذا استخدم المحلل مشغل الاستثناء الموسع (EXCEPT ALL) على نفس البيانات، فإن الاستعلام سيعمل بالمنطق الرياضي للمجموعات المتعددة. سيقوم المحرك بحساب تكرار القيد في الجدول الأول (3 مرات) وطرح تكراره في الجدول الثاني (مرة واحدة)، لتكون النتيجة الصافية ظهور السجل المالي مرتين بدقة مطلقة في جدول المخرجات. توضح هذه الحالة التطبيقية أن اختيار المشغل ليس مسألة تفضيل شكلي، بل هو قرار منهجي محوري؛ حيث يُفضل مشغل EXCEPT للبيانات الديموغرافية والطبية التي تبحث عن قوائم أفراد فريدة، بينما يُعد مشغل EXCEPT ALL الخيار الحتمي للبيانات المحاسبية، والتأمينية، وسلاسل الإمداد، وحركات المخزون التي تعتمد على الدقة العددية المحضة لكل عملية مسجلة.
6. الفروق التقنية بين مشغل EXCEPT والربط الخارجي الأيسر (LEFT JOIN)
6.1 صياغة الاستعلام البديل باستخدام LEFT JOIN مع شرط IS NULL
في بيئة لغة الاستعلام الهيكلية داخل ساس، يمكن تحقيق النتيجة المنطقية لمشغل الاستثناء باستخدام تقنية الربط الخارجي الأيسر (LEFT JOIN) مقترنة بشرط تصفية يفحص القيم المفقودة (WHERE … IS NULL). تستند هذه التقنية المعمارية إلى دمج الجدولين بالكامل استناداً إلى حقل مفتاحي مشترك (Key Column)، مع الاحتفاظ بجميع سجلات الجدول الأيسر ووضع قيم مفقودة (Missing Values) في حقول الجدول الأيمن للسجلات التي لا تجد لها تطابقاً. ومن خلال إضافة شرط التحقق من كون المفتاح الأيمن مفقوداً، يتم عزل السجلات التي تنتمي حصرياً للجدول الأيسر دون نظير في الأيمن.
تتسم صياغة الربط الخارجي الأيسر بمرونة عالية ولكنها تتطلب كتابة تعليمات برمجية أكثر تفصيلاً وتعقيداً مقارنة بمشغل الاستثناء المباشر. فبينما يكتفي مشغل EXCEPT بعبارة دمج مختصرة وواضحة تركز على المفهوم المجموعي، يتطلب LEFT JOIN صياغة جملة الربط بدقة، وتحديد شروط المطابقة في عبارة ON لكل عمود من الأعمدة المقارنة، ثم صياغة شرط IS NULL في عبارة WHERE التصفوية. هذا التعقيد اللفظي يزيد من احتمالية وقوع الأخطاء النحوية أو المنطقية، لاسيما عند مقارنة جداول تحتوي على عدد كبير من المتغيرات المركبة.
ومع ذلك، يوفر أسلوب LEFT JOIN ميزة هيكلية بالغة القوة لا يستطيع مشغل EXCEPT تقديمها بصيغته التقليدية؛ إذ يتيح الربط الخارجي للمحلل استرجاع وتضمين حقول وبيانات إضافية من الجدول الأيسر دون أن تكون مشمولة بالضرورة في عملية المقارنة والمطابقة. ففي مشغل EXCEPT، تخضع كافة الأعمدة المكتوبة في عبارة SELECT لعملية المقارنة الإجبارية، في حين يسمح LEFT JOIN بتحديد حقل واحد كمعرف للمقارنة (ID مثلاً) مع إمكانية استعراض عشرات المتغيرات الوصفية الأخرى المرتبطة به في الجدول المسترجع دون إدخالها في شروط التطابق، مما يمنحه تفوقاً في بعض سيناريوهات بناء لوحات التحكم والتقارير الإحصائية التفصيلية.
6.2 مقارنة كفاءة التنفيذ واستهلاك الموارد في محرك ساس
تخضع المفاضلة بين مشغل EXCEPT والربط الخارجي الأيسر لمعايير أداء صارمة تتعلق بحجم البيانات، وطبيعة توزيعها، وبنية الموارد المتاحة لنظام ساس. عند معالجة الجداول الصغيرة إلى المتوسطة، يكون الفارق الزمني بين الأسلوبين غير محسوس للمستخدم النهائي؛ إلا أن التباين يظهر بوضوح عند الانتقال إلى الجداول المليونية وقواعد البيانات الضخمة (Big Data). في مثل هذه البيئات المعقدة، تلعب بنية خوارزمية التنفيذ الداخلية دوراً حاسماً في سرعة إنجاز الاستعلام واستقرار النظام الخادم.
يميل مشغل EXCEPT القياسي إلى استهلاك موارد المعالجة المركزية (CPU) ومساحة التخزين المؤقت في مكتبة WORK بشكل مكثف نتيجة لعمليات الفرز الضمني وإلغاء الازدواجية التي يفرضها بطبيعته الهيكلية. فإذا لم تكن البيانات مدعومة بفهارس مرتبة مسبقاً، يضطر المحرك إلى إنشاء نسخ وسيطة ومطابقتها سجلاً بسجل عبر خوارزميات الفرز التتابعي. في المقابل، يمتلك محرك PROC SQL خيارات تحسين متقدمة (Optimization Paths) عند التعامل مع استعلامات JOIN، حيث يمكنه الاستفادة الفورية من الفهارس البسيطة والمركبة (Simple and Composite Indexes) الموجودة على الجداول، مما يتيح له الوصول المباشر إلى السجلات المتطابقة باستخدام خوارزميات البحث في الأشجار الثنائية الفهرسية دون الحاجة إلى قراءة ومسح كامل ملفات البيانات من القرص الصلب.
من ناحية إدارة الذاكرة، يمكن لتقنية LEFT JOIN مع شرط IS NULL أن تكون أكثر كفاءة واقتصاداً في استهلاك الذاكرة في الحالات التي تكون فيها الفهارس مهيأة مسبقاً على مفاتيح الربط. ولكن في حال غياب الفهارس، قد يلجأ المحرك في كلتا الحالتين إلى استخدام تقنيات مثل الربط بالتجزئة (Hash Joins) أو الربط بالفرز والدمج (Sort-Merge Joins). وبناءً على ذلك، توصي أفضل الممارسات المنهجية لمبرمجي ساس باستخدام مشغل EXCEPT للعمليات المجموعية النقية التي تتطلب بساطة التعبير والتحقق من التطابق التام لكافة الحقول، بينما يُوصى بالاعتماد على LEFT JOIN في بيئات قواعد البيانات الضخمة التي تعتمد بشكل جوهري على البنى الفهرسية والربط عبر مفاتيح محددة.
7. التعامل مع القيم المفقودة (Missing Values) وتطابق البيانات
7.1 معالجة القيم المفقودة في المتغيرات الرقمية والنصية
تعتبر القيم المفقودة (Missing Values) من التحديات الهيكلية المتأصلة في تحليل البيانات الواقعية، وتتطلب فهماً عميقاً لكيفية تعامل محرك ساس معها أثناء تنفيذ العمليات المجموعية. في خطوة البيانات التقليدية (DATA Step)، يتم تمثيل القيمة المفقودة الرقمية بنقطة (.) وتعتبر رياضياً أصغر من أي قيمة عددية سالبة، بينما تُمثل القيمة المفقودة النصية بسلسلة فارغة من المسافات (‘ ‘). وتخضع هذه القيم لقواعد خاصة عند مقارنتها في الشروط المنطقية العادية، مما قد يؤدي أحياناً إلى نتائج ملتبسة إذا لم ينتبه المبرمج لسلوكيات الترتيب والمقارنة.
عند استخدام مشغل EXCEPT في PROC SQL، يتم التعامل مع القيم المفقودة وفقاً للمنطق القياسي لعمليات المجموعات في SQL، والذي يختلف جوهرياً عن سلوك المقارنات الشرطية الفردية. في الشروط العادية (WHERE Clause)، تكون نتيجة مقارنة قيمة مفقودة بأخرى مفقودة هي “غير معروف” (NULL = NULL تعيد False أو Unknown). أما في سياق مشغل الاستثناء والعمليات المجموعية، فإن محرك ساس يعتبر القيمتين المفقودتين “متطابقتين كلياً” (Treated as Equal for Set Operations). هذا يعني أنه إذا كان هناك سجل في الجدول الأول يحتوي على قيمة مفقودة (.)، وكان هناك سجل مطابق في الجدول الثاني يحتوي أيضاً على قيمة مفقودة في نفس العمود، فإن المحرك يعتبرهما متماثلين تماماً ويقوم باستبعاد السجل من المخرجات.
يفرض هذا السلوك على محلل البيانات تبني استراتيجيات استباقية قبل تمرير البيانات إلى مشغل الاستثناء. إذا كان الهدف التحليلي يعتبر السجلات ذات القيم المفقودة كيانات فريدة لا ينبغي استبعادها أو إسقاطها لمجرد غياب البيانات، فيتعين تصفية هذه السجلات مسبقاً، أو استخدام دوال التعويض التلقائي مثل دالة COALESCE للأرقام ودالة COALESCEC للنصوص لملء الفراغات بقيم بديلة واضحة تعكس الطبيعة الإحصائية للعينة، مما يضمن خضوعها للاستثناء وفق معايير مدروسة ومنهجية واضحة.
7.2 حساسية حالة الأحرف والمسافات البادئة واللاحقة
تشكل المتغيرات النصية (Character Variables) أرضية خصبة لظهور أخطاء عدم التطابق المنطقي عند استخدام مشغل EXCEPT، ويعود ذلك بالدرجة الأولى إلى حساسية نظام ساس الصارمة لحالة الأحرف اللاتينية (Case Sensitivity) وللمسافات الفارغة (Blanks). يعتبر محرك ساس السلسلة النصية “SAS” مختلفة تماماً عن السلسلة “sas” أو “Sas”، نظراً لاختلاف الشفرة الرقمية (ASCII/EBCDIC) لكل حرف. ونتيجة لذلك، إذا كان الجدول الأول يحتوي على اسم العميل بأحرف كبيرة والجدول الثاني يحتوي على الاسم نفسه بأحرف صغيرة، فإن مشغل EXCEPT سيعتبرهما سجلين متنافرين ولن يستبعد السجل، مما يؤدي إلى تسرب صفوف كان من المفترض منطقياً استبعادها.
للتغلب على هذه الإشكالية الشائعة، تقتضي قواعد البرمجة الرصينة توحيد حالة الأحرف برمجياً داخل جملة الاستعلام ذاتها. يمكن تطبيق دالة رفع الأحرف UPCASE أو خفض الأحرف LOWCASE على المتغيرات النصية المسترجعة في كلا شطري الاستعلام، مما يضمن أن تتم المقارنة المجموعية على نص موحد الشكل بغض النظر عن طريقة إدخاله الأولية في قواعد البيانات التشغيلية. يضمن هذا الإجراء إغلاق ثغرة التباين النصي الناتجة عن أخطاء الإدخال اليدوي أو تباين مصادر البيانات.
إلى جانب حالة الأحرف، تبرز مشكلة المسافات البادئة واللاحقة (Leading and Trailing Spaces) التي تلحق بالقيم النصية نتيجة لتفاوت تعريف أطوال المتغيرات بين الجداول. فإذا عُرّف متغير في الجدول الأول بطول 20 خانة وتم تخزين كلمة “Health” متبوعة بـ 14 مسافة، وعُرّف نفس المتغير في الجدول الثاني بطول 10 خانات متبوعاً بـ 4 مسافات، فقد يؤدي ذلك في بعض محركات الربط إلى فشل التطابق. على الرغم من أن PROC SQL يقوم عادة بمساواة المسافات اللاحقة أثناء المقارنة النصية، فإن الممارسات الاحترافية تقتضي تطبيق دوال التنظيف النصي مثل TRIM و STRIP لإزالة كافة المسافات الزائدة غير الضرورية، وضمان نقاء واتساق السلاسل النصية قبل إخضاعها للمنطق الرياضي لمشغل الاستثناء.
8. تحسين الأداء وإدارة الذاكرة عند تطبيق EXCEPT على قواعد البيانات الضخمة
8.1 استراتيجيات تحسين استعلامات الفرق في الجداول المليونية
عندما تتسع مجموعات البيانات لتتجاوز ملايين الملاحظات وعشرات الأعمدة، يصبح تنفيذ مشغل الاستثناء بدون تخطيط مسبق مغامرة محفوفة بالمخاطر قد تستنزف موارد الخادم وتؤدي إلى بطء شديد أو توقف المعالجة نتيجة امتلاء مساحات التخزين المؤقت. تتمثل أولى القواعد الذهبية لتحسين الأداء في التخلي التام عن استخدام علامة النجمة (*) في جملة SELECT. يؤدي استخدام النجمة إلى إجبار المحرك على سحب ومقارنة وفرز جميع الحقول الموجودة في الجداول، بما في ذلك الحقول الوصفية الطويلة التي لا قيمة لها في تحديد تباين المجموعات، مما يضاعف العبء التخزيني والحسابي بلا طائل.
تتمثل الاستراتيجية المثلى في حصر الأعمدة المسترجعة في الحد الأدنى اللازم لتحقيق الهدف التحليلي، والتركيز على المتغيرات المفتاحية المحددة للكيانات. بالإضافة إلى ذلك، يجب تطبيق شروط التصفية والتضييق المسبق عبر عبارات WHERE داخل كل شطر استعلام على حدة قبل تطبيق مشغل EXCEPT. إن تصفية البيانات عند المصدر وتقليص حجم المجموعات المتنافسة بنسبة 50% مثلاً قبل وصولها إلى مرحلة المقارنة المجموعية ينعكس بشكل مضاعف وأسي على سرعة تنفيذ عملية الفرق والفرز الداخلي المصاحب لها.

علاوة على ذلك، تلعب خيارات النظام في ساس (System Options) دوراً حيوياً في تمكين محرك PROC SQL من استغلال العتاد المادي للخادم بأقصى كفاءة ممكنة. من أبرز هذه الخيارات خيار BUFSIZE وخيار BUFNO، اللذان يتحكمان في حجم وعدد حوافظ الذاكرة المخصصة لقراءة البيانات من القرص، وخيار SORTSIZE الذي يحدد الحد الأقصى لمساحة الذاكرة العشوائية (RAM) المسموح لمحرك الفرز باستخدامها قبل اللجوء إلى التخزين المؤقت البطيء على القرص الصلب. إن ضبط هذه المعلمات التقنية بما يتناسب مع حجم البيانات والذاكرة المتاحة للمؤسسة يمنع حدوث عنق الزجاجة (Bottleneck) ويسرع إنجاز استعلامات الفرق المليونية بشكل لافت.
8.2 تحليل سجل التشغيل (SAS Log) وأوامر التشخيص
يمثل سجل التشغيل (SAS Log) النافذة الأساسية للمطور لمراقبة كفاءة التنفيذ وتشخيص مكامن الضعف والقصور في استعلامات PROC SQL. لا ينبغي للمبرمج الاكتفاء بقراءة رسائل النجاح أو خلو السجل من الأخطاء الصريحة، بل يجب تفعيل أدوات التشخيص المتقدمة المدمجة في النظام لتحليل البنية الهيكلية للاستعلام. من أهم هذه الأدوات خيار _METHOD وخيار _TREE، اللذان يمكن تفعيلهما ضمن تعليمة PROC SQL لمشاهدة خطة التنفيذ المنهجية وشجرة القرارات البرمجية التي اتخذها المحرك لمعالجة مشغل EXCEPT.
عند تفعيل هذه الخيارات التشخيصية، يطبع ساس في سجل التشغيل رموزاً تفصيلية توضح كيفية تعامل المحرك مع المجموعات؛ مثل استخدام خوارزمية الفرز (sqlsrt) أو خوارزمية التجزئة (sqlhash) أو القراءة الخطية الشاملة للجداول (sqltab). يتيح هذا التوثيق للمهندس فهم ما إذا كان النظام قد نفذ فرزاً مزدوجاً غير مرغوب فيه، وتحديد ما إذا كانت هناك حاجة ملحة لإنشاء فهارس مساعدة تعفي المحرك من إجراءات الفرز المرهقة، مما يسهم في اتخاذ قرارات تحسين مدعومة بالبيانات المعمارية الدقيقة.
إضافة إلى ذلك، يوفر تفعيل خيار النظام FULLSTIMER تقريراً إحصائياً شاملاً ودقيقاً يرافق نهاية تنفيذ كل خطوة برمجية. يوثق هذا التقرير كلاً من الوقت الفعلي المستغرق (Real Time)، ووقت المعالجة المركزية (CPU Time)، وأعلى نقطة لاستهلاك الذاكرة (Memory Usage)، وحجم عمليات الإدخال والإخراج للقرص الصلب. إن مراقبة التباعد بين الوقت الفعلي ووقت المعالجة يعطي مؤشراً حاسماً على ما إذا كان الاستعلام يعاني من بطء في عمليات قراءة القرص أو امتلاء في مكتبة التخزين المؤقت WORK، مما يتيح اتخاذ التدابير الهندسية اللازمة لتصحيح المسار قبل إطلاق الشيفرات في بيئات الإنتاج الفعلية.
9. مقارنة مشغل EXCEPT في PROC SQL مع أسلوب خطوة البيانات (DATA Step MERGE)
9.1 تنفيذ الاستثناء التقليدي باستخدام MERGE والمتغير IN=
قبل ظهور وانتشار إجراء PROC SQL في الإصدارات الأولى من نظام ساس، كانت خطوة البيانات التقليدية (DATA Step) باستخدام تعليمة MERGE المرفقة بخيارات المتابعة المتغيرة IN= هي الوسيلة المعمارية الوحيدة لتنفيذ عمليات المجموعات واستخراج الفروقات بين الجداول. يعتمد هذا الأسلوب الكلاسيكي على تتبع مصدر السجل أثناء عملية الدمج المتزامن؛ حيث يقوم المطور بتعيين متغير منطقي مؤقت لكل جدول مساهم في الدمج (مثلاً IN=a للجدول الأول و IN=b للجدول الثاني). تأخذ هذه المتغيرات القيمة الثنائية 1 إذا كان السجل الحالي قادماً من ذلك الجدول المعين، وتأخذ القيمة 0 إذا لم يكن كذلك.
لمحاكاة مشغل الاستثناء تماماً باستخدام خطوة البيانات واستخراج السجلات الخاصة بالجدول الأول فقط دون الثاني، يكتب المبرمج شرطاً فرزياً باستخدام عبارة التصفية: IF a AND NOT b. يفحص هذا التعبير المنطقي كل ملاحظة تمر عبر مساحة العمل المؤقتة (Program Data Vector – PDV)، فإذا كانت الملاحظة تنتمي للجدول الأول وليست ممثلة في الجدول الثاني، يتم كتابتها وتثبيتها في ملف البيانات المستهدف، بينما يتم إسقاط وتجاهل كافة السجلات الأخرى سواء كانت مشتركة بين الجدولين أو مقتصرة على الجدول الثاني.
ومع ذلك، يفرض أسلوب خطوة البيانات التقليدي شرطاً صارماً لا مفر منه، وهو ضرورة الفرز المسبق الكامل لكلا الجدولين وفق متغيرات المطابقة ذاتها باستخدام الإجراء PROC SORT، أو وجود فهارس تطابق محددة مسبقاً على متغير BY. إذا حاولت تنفيذ خطوة MERGE دون فرز مسبق متسق، فإن خطوة البيانات ستتوقف فوراً ملقية برسائل خطأ حرجة في سجل التشغيل، مما يجعل هذه التقنية تتطلب كتلتين برمجيتين إضافيتين للفرز قبل تنفيذ خطوة الاستثناء الفعلية، وهو ما يرفع من طول الكود البرمجي ويزيد من تعقيده الظاهري مقارنة بالأناقة التعبيرية لمشغل EXCEPT في PROC SQL.
9.2 تحليل الفروق الوظيفية ومفاضلة الاستخدام
يكشف التحليل المقارن بين الأسلوبين عن فروق وظيفية وهيكلية عميقة تجعل لكل منهما سياقات تفضيل متباينة في بيئات العمل التحليلية. تتفوق لغة PROC SQL ومشغل EXCEPT بالمرونة البرمجية الفائقة والقدرة على الاستغناء عن الفرز اليدوي المسبق والمصرح به في الكود؛ إذ يتولى المحرك داخلياً وتلقائياً إدارة الترتيب والفرز دون تدخل المطور. كما تتطابق صياغة EXCEPT مع المعايير الدولية لقواعد البيانات، مما يسهل نقل الأكواد ومشاركتها مع مطورين قادمين من خلفيات تقنية أخرى مثل أوراكل أو بوستجرسيكول أو منصات السحب الحاسوبية المتنوعة دون الحاجة لتعلم خصوصيات خطوة البيانات في ساس.

في المقابل، تتمتع خطوة البيانات التقليدية (DATA Step MERGE) بقدرات تحكم تشغيلية متناهية الصغر لا يمكن مجاراتها عبر مشغلات المجموعات البسيطة. تتيح خطوة البيانات للمطور معالجة القيم وتعديلها، وبناء متغيرات جديدة مشتقة، وتنفيذ جمل شرطية متداخلة معقدة أثناء عملية الدمج والاستثناء في دورة معالجة واحدة (Single Pass) للبيانات. بالإضافة إلى ذلك، تتفوق خطوة البيانات بوضوح في التعامل مع الجداول التي تم فرزها وأرشفتها مسبقاً؛ حيث لا تحتاج إلى أي فرز إضافي، وتتم قراءة السجلات مباشرة من القرص الصلب وبشكل تتابعي خفيف جداً على الذاكرة، بينما قد يُصر مشغل EXCEPT على الفرز الداخلي لإلغاء الازدواجية.
توضح المعايير المهنية للاختيار أن مشغل EXCEPT يمثل الحل الأمثل في سيناريوهات التحليل الاستكشافي، ومطابقة العينات السريعة، وأعمال التحقق من البيانات وجودتها، وعندما تكون بساطة الكود وقابليته للصيانة الجماعية هي الأولوية القصوى. في المقابل، يظل أسلوب خطوة البيانات (MERGE مع IN=) هو الخيار الأرصن والأقوى في خطوط الإنتاج المعقدة (Data Pipelines) التي تتطلب تحويلاً وتطهيراً متزامناً للبيانات، أو عند التعامل مع ملفات ضخمة ومفروزة مسبقاً وتخضع لقيود صارمة في استهلاك الذاكرة العشوائية.
10. الأخطاء الشائعة واستكشاف المشكلات وإصلاحها عند استخدام EXCEPT
10.1 الأخطاء التركيبية وتفاوت مواصفات الأعمدة المسترجعة
يواجه العديد من مبرمجي ساس، لاسيما المبتدئين أو المنتقلين حديثاً من لغات استعلام أخرى، مجموعة من الأخطاء التركيبية الشائعة عند تطبيق مشغل EXCEPT. الخطأ الأكثر تكراراً هو خطأ عدم تطابق عدد الأعمدة المستدعاة في كلا الشطرين، والذي يتجلى في سجل التشغيل بالرسالة التحذيرية الشهيرة: ERROR: Number of columns does not match across the SELECT statements. يحدث هذا الخطأ غالباً عند إضافة حقل جديد في الشطر الأول ونسيان إضافته في الشطر الثاني، أو عند استخدام النجمة (*) في كلا الشطرين مع تباين البنية الهيكلية للجداول في مساحة المكتبات.
الخطأ التركيبي الثاني بالغ الخطورة هو خطأ تعارض الأنواع (Data Type Mismatch)، والذي ينتج عندما يتوافق الاستعلامان عددياً في الأعمدة، ولكن يختلفان في نوع البيانات المتقابلة وفق الترتيب؛ كأن يقابل عموداً رقمياً عمود نصي. يرفض محرك ساس تنفيذ الاستعلام في هذه الحالة لحماية البيانات من التحويلات العشوائية. لحل هذه الإشكالية دون الحاجة لتعديل الجداول الأصلية، يتعين على المطور استخدام دوال التحويل القسري الصريح للأنواع داخل جملة SELECT؛ مثل استخدام دالة INPUT لتحويل المتغيرات النصية إلى رقمية، أو استخدام دالة PUT لتحويل الأرقام إلى نصوص منسقة، مما يضمن التوافق النوعي الكامل قبل تفعيل مشغل الاستثناء.
وثمة خطأ تركيبي آخر يرتبط بالترتيب العشوائي للأعمدة في عبارات الاسترجاع. إذا قام المبرمج باستدعاء المتغيرات (العمر، الوزن) في الاستعلام الأول، واستدعى (الوزن، العمر) في الاستعلام الثاني، فلن يُصدر النظام أي خطأ تركيبي نظراً لتطابق عدد الأعمدة وتطابق نوعها الرقمي في كلا الطرفين، ولكن الكود سينفذ مقارنة شاذة تؤدي إلى تشويه النتائج واسترجاع كافة الصفوف تقريباً لعدم تطابق الأعمار بالأوزان. يقتضي تفادي هذا الخطأ الصامت التوثيق الدقيق ومراجعة ترتيب الأعمدة حرفياً والتأكد من مطابقتها الدلالية التامة قبل الشروع في فحص النتائج المستخرجة.
10.2 الأخطاء المنطقية والنتائج غير المتوقعة
تعد الأخطاء المنطقية في استعلامات المجموعات أشد خطورة من الأخطاء التركيبية، لكونها لا توقف تنفيذ البرنامج ولا تُصدر رسائل تحذيرية في سجل التشغيل، بل تعيد مخرجات “خاطئة ظاهرياً” تبدو وكأنها صحيحة. من أبرز هذه الظواهر استرجاع جدول مخرجات فارغ تماماً (Zero Rows) رغم يقين المحلل بوجود اختلافات بين المجموعتين. يعود السبب في معظم هذه الحالات إلى عكس ترتيب الجداول عن غير قصد في الاستعلام، مما يجعل النظام يطرح المجموعة الكبيرة من المجموعة الصغيرة أو العكس، أو وجود قيم مفقودة في حقول حيوية أدت إلى تماثل السجلات منطقياً واستبعادها بالكامل.
تتمثل المشكلة المنطقية الشائعة الأخرى في الفقدان غير المبرر للتكرارات المحاسبية والإحصائية. يغفل الكثير من المطورين عن حقيقة أن مشغل EXCEPT القياسي يمحو تلقائياً التكرارات داخل الجدول الأول، ويتفاجأ المحلل بأن تقرير الحركات المالية أو تعداد المرضى يظهر أرقاماً أقل بكثير من الواقع التشغيلي. يُعزى هذا الخطأ مباشرة إلى إغفال استخدام الكلمة المفتاحية ALL، حيث كان ينبغي كتابة EXCEPT ALL للحفاظ على التكرارات المشروعة التي تعبر عن أحداث مستقلة في الواقع التجريبي أو المالي.
كذلك تبرز مسألة تفاوت أطوال المتغيرات النصية (Length Attribute) كأحد المصادر الخفية للأخطاء المنطقية. إذا كان الجدول الأول يمتلك متغيراً بطول 10 خانات يحمل قيمة “ABC”، والجدول الثاني يمتلك متغيراً بطول 50 خانة يحمل نفس القيمة، فقد يؤدي ذلك في بعض الظروف المعقدة للربط أو عند التصدير إلى قواعد بيانات وسيطة إلى اعتبار الحقول غير متطابقة بسبب حساب المسافات الإضافية المضمنة في البنية التخزينية. ولمعالجة هذه المشكلات واستكشافها منهجياً، يُوصى بعزل الاستعلامات، واختبار كل متغير على حدة، وتطبيق استعلامات العد التكراري (COUNT) للتحقق خطوة بخطوة من سلامة المنطق البرمجي قبل اعتماده في التقارير النهائية.
11. تطبيقات متقدمة: استخدام EXCEPT مع المجموعات الفرعية والتصفية المعقدة
11.1 دمج الاستعلامات المتداخلة (Subqueries) مع مشغل الاستثناء
تتضاعف القوة التحليلية لمشغل الاستثناء عندما يتم دمجه داخل هياكل استعلامية متداخلة (Nested Subqueries) ومتعددة الطبقات ضمن بيئة PROC SQL. في السيناريوهات المعقدة، لا تكون البيانات المدخلة جاهزة في جداول ساكنة ومستقلة، بل تتطلب استخلاصاً وتجميعاً وتصفية متقدمة في الوقت الفعلي قبل إخضاعها للمقارنة المجموعية. يتيح ساس للمطور تضمين جمل EXCEPT كاملة داخل أقواس رياضية واعتبارها جدولاً مؤقتاً مشتقاً يتم استدعاؤه في عبارة FROM الرئيسية، أو توظيفها كمعيار تصفية شرطي داخل عبارات WHERE أو HAVING عبر مشغلات الفحص مثل IN أو EXISTS.
من الأمثلة الساطعة على هذا التطبيق المتقدم ما يجري في تحليل بيانات التجارب السريرية للأدوية (Clinical Trials)، حيث تتطلب البروتوكولات الطبية عزل وتتبع العينات الضابطة الخاضعة لمعايير استبعاد بالغة التعقيد والصرامة. يمكن بناء استعلام متداخل يستخلص من قاعدة البيانات المركزية المرضى الذين استجابوا للعلاج، ويطرح عبر EXCEPT استعلاماً فرعياً آخر يستخلص المرضى الذين ظهرت لديهم آثار جانبية معينة أو تناولوا أدوية متداخلة محظورة خلال فترة التجربة. يتيح هذا الدمج المتداخل تصفية العينات الطبية على مستويات متعددة في خطوة استعلامية واحدة فائقة الإحكام والسرعة.
بالإضافة إلى ذلك، يمكن دمج مشغل الاستثناء مع دوال التجميع الرياضي الإحصائي والشرطي؛ كأن يتم استخراج السجلات بناءً على شروط تجميعية محددة في عبارة HAVING قبل إخضاعها للاستثناء. يتيح هذا النمط الهجين استخراج وحدات التحليل التي حققت معدلات مبيعات معينة أو معدلات حضور محددة واستثناء الفئات التي لم تحقق تلك المعدلات، مما يمنح مديري النظم ومحللي البيانات الكبار أدوات رشيقة لبناء استعلامات ديناميكية تلبي أدق متطلبات الأعمال دون الحاجة لإنشاء جداول وسيطة متعددة ترهق مساحات التخزين.
11.2 الجمع بين مشغلات المجموعات المتعددة (UNION و INTERSECT و EXCEPT)
في معماريات البيانات شديدة التعقيد، تبرز الحاجة في كثير من الأحيان إلى دمج عدة مشغلات مجموعات في استعلام موحد واحد لحل معضلات تصنيفية معقدة تتضمن الاتحاد والتقاطع والفرق في آن واحد. عند كتابة مثل هذه الاستعلامات المركبة، يجب أن يكون المطور على دراية تامة بالقواعد الصارمة التي تحكم “أسبقية تنفيذ العمليات” (Operator Precedence) داخل محرك PROC SQL في ساس. وفقاً للمعايير القياسية للغة SQL المعتمدة في ساس، يحظى مشغل التقاطع (INTERSECT) بأعلى أسبقية في التنفيذ، ويليه في الأسبقية كل من مشغلي الاتحاد (UNION) والاستثناء (EXCEPT) بالتساوي، حيث يتم تنفيذهما من اليسار إلى اليمين ما لم تتدخل الأقواس لإعادة توجيه المسار.
تعتبر الأقواس الرياضية () الأداة الاستراتيجية الحتمية لفرض الترتيب المنطقي المطلوب وضمان دقة النتائج، تماماً كما هو متبع في المعادلات الجبرية الكلاسيكية. لنفترض حالة عملية تتطلب استخراج جميع العملاء النشطين المسجلين في الفرع (أ)، والمستثنى منهم العملاء الذين قاموا بالشراء في الفرع (ب) والفرع (ج) معاً. إذا تمت كتابة الاستعلام تسلسلياً دون أقواس، فقد يبدأ المحرك بتنفيذ عمليات التقاطع أو الاتحاد بطريقة تخالف نية المحلل المنطقية، مما ينتج عنه مخرجات مضللة. ومن خلال استخدام الأقواس للفصل بين الكتل البرمجية، يضمن المطور تنفيذ ناتج اتحاد أو تقاطع معين أولاً، ثم تطبيق عملية الفرق المجموعي على النتيجة الوسيطة بدقة رياضية لا تحتمل اللبس.
لتوضيح ذلك بتطبيق عملي شامل: عند الرغبة في استخراج العناصر المتواجدة في الجدول A والمستثناة من الحصيلة الإجمالية الناتجة عن اتحاد الجدول B والجدول C، تتم صياغة الاستعلام بحيث يُكتب الاستعلام الخاص بالجدول A متبوعاً بمشغل EXCEPT، وتوضع الكتلة البرمجية التي تدمج الجدولين B و C عبر مشغل UNION داخل أقواس مستقلة بالكامل: A EXCEPT (B UNION C). يضمن هذا الهيكل التنظيمي قيام محرك ساس بحساب الكتلة المتحدة أولاً، ثم تنفيذ الطرح المجموعي من A ثانياً. إن توثيق تدفق البيانات المنطقي عبر الأقواس يحمي الشيفرات البرمجية من تقلبات التفسير الداخلي للمحرك ويسهل صيانتها وتدقيقها في المشاريع الإحصائية الضخمة.
12. أفضل الممارسات المنهجية لتوثيق وضمان جودة استعلامات EXCEPT
12.1 قواعد التوثيق البرمجي والوضوح المعياري للكود
يمثل التوثيق البرمجي الرصين والالتزام بالمعايير الهندسية في كتابة الشيفرات ركيزة أساسية لضمان استدامة المشاريع الإحصائية في ساس وقابليتها للتطوير والمراجعة الدورية. نظراً لأن مشغل EXCEPT يعتمد على مقارنة موضعية للأعمدة، فإن كتابة الأكواد بأسلوب مضغوط وغير منظم تزيد من احتمالية حدوث أخطاء خفية يصعب رصدها أثناء المراجعة السريعة. تقتضي أفضل الممارسات إدراج كتل تعليقية توضيحية (Comments) تسبق كل شطر من شطري الاستعلام، تشرح بوضوح الغرض المنطقي والرياضي من استدعاء هذه المجموعة واستبعاد تلك.
يجب كذلك الالتزام الصارم بتنسيق الكود من خلال استخدام المسافات البادئة المتسقة (Indentation)؛ بحيث يتم وضع كل مشغل مجموعة في سطر مستقل يبرز التوازي الهيكلي بين الاستعلامين المتقابلين. كما يُنصح دائماً بتسمية الأعمدة المسترجعة بعناوين صريحة ومعيارية، واستخدام خيار إنشاء الجداول الدائمة أو المؤقتة ذات الأسماء المعبرة (مثل CREATE TABLE Work.Unique_Patients AS) بدلاً من طباعة المخرجات مباشرة في نافذة التقارير، مما يتيح تتبع مسار البيانات (Data Lineage) وإخضاع الجدول الناتج لفحوصات لاحقة.
علاوة على ذلك، يُعد استخدام أوامر التوثيق والتقارير المضمنة في ساس، مثل تعليمتي TITLE و FOOTNOTE، ممارسة لا غنى عنها في بيئات العمل المهنية. يجب أن تعكس العناوين بوضوح أطراف العملية المجموعية واتجاهها الزمني أو الهيكلي؛ كأن يُذكر في العنوان: “سجلات المجموعة الضابطة بعد استبعاد حالات التداخل التجريبي”. يسهم هذا التوثيق الدقيق في إزالة أي غموض قد يعتري متخذي القرار والباحثين غير التقنيين عند استعراض النتائج في تقارير الأعمال والمنشورات العلمية.
12.2 استراتيجيات التحقق وضمان جودة البيانات المستخرجة
لا تنتهي مهمة مبرمج ساس بمجرد انتهاء الاستعلام بنجاح وطباعة النتائج، بل تبدأ مرحلة حاسمة تُعرف بـ “ضمان جودة وتكامل البيانات المستخرجة” (Data Quality and Validation). تتمثل أولى استراتيجيات التحقق في إجراء اختبارات مقارنة التعداد الرياضي (Row Count Validation). إذا كان الجدول الأول A يحتوي على 1000 سجل فريد، وكان التقاطع المشترك بين A و B يحتوي على 200 سجل، فيجب بالضرورة الرياضية الحتمية أن يكون عدد سجلات ناتج A EXCEPT B مساوياً تماماً لـ 800 سجل. يمكن للمطور كتابة استعلامات سريعة باستخدام دالة COUNT للتأكد من انطباق هذه الموازنة العددية بدقة.
الاستراتيجية الثانية والأكثر شمولاً تتمثل في توظيف الإجراءات التشخيصية المتقدمة المتوفرة في ساس، وعلى رأسها إجراء المقارنة المعملي PROC COMPARE. يتيح هذا الإجراء المتخصص مقارنة جدول النتائج المسترجع من مشغل الاستثناء بالجدول الأصلي للتحقق من عدم حدوث أي تشويه أو تداخل في قيم المتغيرات النصية والرقمية أثناء عمليات الفرز والتحويل الداخلي، ومراجعة خواص الأعمدة وأطوالها لضمان مطابقتها للمواصفات القياسية المطلوبة.
أخيراً، تقتضي الممارسات المتقدمة في بيئات الإنتاج بناء “اختبارات تأكيد آلية” (Automated Assertions) ومسارات تدقيق مبرمجة في لغة الماكرو (SAS Macro Language). تهدف هذه الاختبارات إلى فحص جدول المخرجات آلياً؛ فإذا تم اكتشاف أي سجل من سجلات الجدول B قد تسرب بالخطأ إلى مخرجات الاستثناء نتيجة خطأ منطقي أو كتابي، يُصدر الماكرو تحذيراً فورياً ويوقف تدفق المعالجة. يضمن هذا النهج الهندسي الصارم حماية المنظومة التحليلية من الأخطاء التراكمية، ويوفر بيئة عمل إحصائية عالية الموثوقية وقابلة للتكرار العلمي والمهني في كافة الظروف والأوقات.
خاتمة
لقد أثبت مشغل الاستثناء EXCEPT في إجراء PROC SQL بنظام ساس أنه ليس مجرد تعليمة استعلامية عادية، بل هو أداة جبرية متكاملة وفائقة القوة تعيد صياغة كيفية تعامل المحللين ومهندسي البيانات مع عمليات الفرق المجموعي واستبعاد الملاحظات المشتركة. لقد استعرضت هذه الدراسة المستفيضة الأبعاد النظرية للمشغل المستندة إلى أسس الجبر العلائقي، وفصلت القواعد النحوية والاشتراطات التركيبية الصارمة للأعمدة والبيانات، موضحة السلوك التلقائي للمشغل في إزالة التكرارات والفروق الدقيقة التي تنشأ عند تفعيل الكلمة المفتاحية ALL للحفاظ على الدقة العددية في التطبيقات المحاسبية والمالية.
كما بينت التحليلات المقارنة التفصيلية الموقع المتميز لمشغل الاستثناء مقارنة ببدائله الشائعة؛ مثل الربط الخارجي الأيسر (LEFT JOIN) وخطوة دمج البيانات التقليدية (DATA Step MERGE)، مسلطة الضوء على المعايير الهندسية الواجب اتباعها للمفاضلة بينها استناداً إلى حجم البيانات ووجود الفهارس وطبيعة الذاكرة المستهلكة. وتظل الإدارة الرصينة للقيم المفقودة، وتنظيف المتغيرات النصية، وضبط خيارات النظام، وبناء اختبارات الجودة المنهجية هي الضمانات الأساسية لنجاح المشاريع الإحصائية الكبرى التي تعتمد على إجراء PROC SQL في استخلاص نتائج قاطعة، دقيقة، وقابلة للاعتماد المؤسسي.
المراجع
- Codd, E. F. (1970). A relational model of data for large shared data banks. Communications of the ACM, 13(6), 377–387. https://doi.org/10.1145/362384.362685
- Date, C. J. (2004). An introduction to database systems (8th ed.). Pearson.
- SAS Institute Inc. (2020). SAS(R) 9.4 SQL Procedure User’s Guide (4th ed.). SAS Institute Inc. https://documentation.sas.com
- Stander, R. (2018). Advanced PROC SQL programming techniques for data manipulation. Proceedings of the SAS Global Forum 2018 Conference, Paper 1982-2018. SAS Institute Inc.
- Lafler, K. P. (2019). PROC SQL: Beyond the basics using SAS (3rd ed.). SAS Institute Inc.
- American National Standards Institute. (2016). Information technology – Database languages – SQL – Part 2: Foundation (SQL/Foundation) (ANSI/ISO/IEC 9075-2:2016). ANSI.
- Delwiche, L. D., & Slaughter, S. J. (2019). The little SAS book: A primer (6th ed.). SAS Institute Inc.