محتويات الدورة

SQL Server / الأساسي / الدرس 3

SELECT والشروط وNULL والترتيب الحتمي

حوّل سؤال العمل إلى شكل نتائج واضح، وتعلّم TOP في SQL Server والمنطق ثلاثي القيم ومجالات التاريخ والأسماء المستعارة وعقد الترتيب الكامل.

وقت القراءة التقريبي: 5 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • كتابة أعمدة وشروط ذات صفوف متوقعة.
  • التعامل مع NULL دون خلطها بالقيم.
  • استخدام TOP مع ORDER BY مستقر.

حدد النتيجة قبل كتابة الصياغة

ابدأ بوحدة النتيجة: صف لكل طلب مفتوح، يتضمن معرفه ومبلغه وموعده الموعود. تحدد SELECT التعبيرات المعروضة، وتحدد FROM المصدر، وتصفّي WHERE الصفوف المفردة. امنح التعبيرات المحسوبة أسماء مستعارة ذات معنى واطلب الأعمدة الضرورية فقط. تجعل SELECT * عقد التطبيق حساساً لتغييرات غير مرتبطة في المخطط وقد تنقل أعمدة نصية كبيرة بلا داع.

يفسر ترتيب المعالجة المنطقي قواعد الأسماء المستعارة. تُقيّم WHERE منطقياً قبل SELECT، ولذلك لا يتاح لها عادة اسم مستعار جديد عُرف في SELECT داخل الكتلة نفسها. تستطيع ORDER BY استخدامه. يشرح هذا النموذج المعنى، لكنه لا يفرض ترتيب التنفيذ المادي الذي يختاره المحسّن. افصل استدلال المعنى عن قراءة الخطة الرسومية.

اختر الصفوف باستخدام TOP وORDER BY

تحد TOP (2) عدد الصفوف المعادة، لكنها دون ORDER BY لا تعني أحدث طلبين أو أكبرهما. لا يمثل الفهرس العنقودي أو ترتيب اعتدت رؤيته عقد ترتيب. يطلب المثال أكبر المبالغ ويكسر التعادل بواسطة OrderId. يجعل هذا الفاصل الفريد الصفين المختارين متوقعين عندما لا تتغير البيانات.

لـ TOP WITH TIES غرض مختلف: يمكن أن تعيد أكثر من العدد المحدد عندما تتعادل الصفوف في جميع تعبيرات الترتيب عند الحد. أضف معرفاً فريداً عندما تريد كسر التعادل، لا عندما يطلب العمل الاحتفاظ بكل الدرجات المتساوية. يظل العرض النهائي بحاجة إلى ORDER BY خارجي؛ ولا يُورث ترتيب داخل عرض تلقائياً.

sql أكبر طلبين مع كسر التعادل
SELECT TOP (2) OrderId, Amount
FROM (VALUES (10,40.00),(11,90.00),(12,90.00))
 AS o(OrderId,Amount)
ORDER BY Amount DESC, OrderId ASC;
الناتج المتوقع
OrderId Amount
11      90.00
12      90.00

يختار المبلغ التنازلي صفي 90.00 ويحدد المعرف التصاعدي ترتيبهما؛ ولا تعبّر TOP وحدها عن هذا السؤال.

استدل بشأن المقارنات المجهولة

تنتج المقارنات التي تتضمن NULL عادة UNKNOWN، ولا تحتفظ WHERE إلا بالنتيجة TRUE. لذلك لا تعثر ShippedOn = NULL على الطلبات غير المشحونة؛ استخدم IS NULL. يستبعد الشرط Amount <> 20 المبالغ المجهولة أيضاً، لأن المجهول ليس صحيحاً ولا خاطئاً. إذا شمل المطلوب القيم المفقودة فعبّر عن ذلك مستقلاً باستخدام OR وأقواس.

يمكن أن تعطي COALESCE قيمة للعرض، لكن استبدال المجهول داخل شرط يغير السؤال. قد يعني غياب الحد الائتماني ضرورة المراجعة، لا رصيداً بلا حدود ولا رصيداً صفرياً. يشكل NOT IN خطراً خاصاً عندما تتضمن قائمته أو استعلامه NULL؛ فقد تنتج UNKNOWN حتى لقيمة تبدو غائبة. استخدم NOT EXISTS مرتبطاً بوضوح لاختبار الغياب.

استخدم مجالات وأقواساً صريحة

يشمل المجال نصف المفتوح بدايته ويستبعد نهايته. بالنسبة لعمود datetime2، يضم الشرطان >= أول يناير و< أول فبراير جميع أوقات يناير دون تخمين آخر جزء من الثانية. تشمل BETWEEN الطرفين، مما يجعل تاريخ نهاية عند منتصف الليل غير مناسب غالباً لتقرير شهر كامل. اجعل أنواع قيم المقارنة متسقة مع العمود.

ترتبط AND بقوة أكبر من OR. عند اختيار الطلبات المفتوحة لواحد من عميلين، اجمع بدائل العملاء بأقواس صريحة. يحتفظ المثال بصفوف يناير غير المشحونة فقط؛ ويستبعد الصف 2 بسبب حد النهاية والصف 3 لوجود تاريخ شحن. توقع مصير كل صف بصورة مستقلة وسيلة فعالة لاكتشاف أخطاء المنطق قبل التفكير في الأداء.

sql طلب يناير غير المشحون
DECLARE @o TABLE (OrderId int, CreatedAt datetime2(0), ShippedOn date NULL);
INSERT @o VALUES
 (1,'2026-01-31T23:59:59',NULL),
 (2,'2026-02-01T00:00:00',NULL),
 (3,'2026-01-10T09:00:00','20260112');
SELECT OrderId FROM @o
WHERE CreatedAt >= '20260101' AND CreatedAt < '20260201'
  AND ShippedOn IS NULL
ORDER BY OrderId;
الناتج المتوقع
OrderId
1

يجب أن يصح شرط التاريخ وشرط NULL معاً؛ ومنتصف ليل فبراير خارج المجال نصف المفتوح.

افصل القيم عن بنية SQL

ينبغي أن تصل مدخلات التطبيق إلى الشروط عبر معلمات محددة النوع. فهي بيانات حتى لو احتوت علامات اقتباس أو نصاً يشبه SQL. يخلط دمج النصوص بين القيمة وبنية الأمر وينشئ خطر الحقن. يوضح DECLARE المحلي النوع لكنه لا يثبت وحده أن التطبيق يستخدم معلمات المشغل. راجع إنشاء الأمر الفعلي عند حدود التطبيق.

تحقق من المجالات والأطوال وفق قواعد العمل، ثم اربط القيم بأنواع SQL Server مناسبة. لا تستبدل المعلمات العادية أسماء الكائنات أو الكلمات المحددة لاتجاه الفرز؛ اخترها من قائمة مسموحة ثابتة. يساعد هذا الفصل الأداء أيضاً بإتاحة إعادة استخدام النص المستقر، مع أن إعادة استخدام الخطط وتفاوت البيانات يحتاجان إلى تحليل دقيق لاحقاً.

الأخطاء الشائعة وإصلاحها

No rows returned by = NULL.

لماذا يحدث؟
تنتج المقارنة بـ NULL القيمة UNKNOWN.
كيف تصلحه؟
استخدم IS NULL أو IS NOT NULL.
كيف تتجنب تكراره؟
أدرج حالات القيم المفقودة ضمن النتائج المتوقعة.

TOP returns changing rows.

لماذا يحدث؟
لا يوجد عقد ترتيب كامل.
كيف تصلحه؟
أضف ORDER BY يعبر عن ترتيب العمل وفاصلاً فريداً عند الحاجة.
كيف تتجنب تكراره؟
راجع التعادل والترتيب ضمن صحة الاستعلام.

Invalid column name.

لماذا يحدث؟
تشير WHERE إلى اسم مستعار ينشأ لاحقاً في SELECT.
كيف تصلحه؟
كرر التعبير أو استخدم جدولاً مشتقاً.
كيف تتجنب تكراره؟
راجع نطاق الأسماء وفق ترتيب المعالجة المنطقي.

اختبر فهمك

1. المبالغ 10 وNULL و30. أيها يبقى مع Amount <> 10؟

اعرض الحل المشروح

تبقى 30 فقط. تنتج NULL القيمة UNKNOWN فتستبعد. لإدراجها اكتب Amount <> 10 OR Amount IS NULL وضع أقواساً عند دمج شرط آخر.

2. أعد أحدث ثلاثة أحداث مع إمكان تساوي الأوقات.

اعرض الحل المشروح

استخدم TOP (3) مع EventTime DESC, EventId DESC بافتراض تفرد EventId. يحدد المعرف قاعدة التعادل. وإن لزم كل المتعادلين فراجع TOP WITH TIES وتعبيرات ترتيبها.

أهم ما تعلمته

  • تحتاج TOP ترتيب عمل صريحاً.
  • تستبعد WHERE النتيجة UNKNOWN.
  • توضح المجالات نصف المفتوحة والمعلمات المحددة النوع المقصود.

المراجع الرسمية