فحص عبارة SELECT

مكتمل

Transact-SQL أو T-SQL، هو لهجة من لغة SQL القياسية ANSI المستخدمة من قِبل منتجات Microsoft SQL وخدماتها. وهي تشبه SQL القياسية. سيكون معظم تركيزنا على عبار SELECT، التي تحتوي إلى حد بعيد على معظم الخيارات والمتغيرات في أي عبارة DML.

دعونا نبدأ من خلال إلقاء نظرة عامة على كيفية معالجة عبارة SELECT. الترتيب الذي تتم به كتابة عبارة SELECT ليس الترتيب الذي يتم تقييمها ومعالجتها به بواسطة محرك قاعدة بيانات SQL Server.

خذ بعين الاعتبار الاستعلام التالي:

SELECT OrderDate, COUNT(OrderID) AS Orders
FROM Sales.SalesOrder
WHERE Status = 'Shipped'
GROUP BY OrderDate
HAVING COUNT(OrderID) > 1
ORDER BY OrderDate DESC;

يتكون الاستعلام من عبارة SELECT، والتي تتكون من جمل متعددة، كل منها يعرف عملية معينة يجب تطبيقها على البيانات التي يتم استردادها. قبل أن ندرس ترتيب وقت التشغيل للعمليات، دعونا نلقي نظرة موجزة على ما يفعله هذا الاستعلام، على الرغم من أن تفاصيل الجمل المختلفة لن تكون مشمولة في هذه الوحدة.

يتم من خلال جملة SELECT إرجاع عمود OrderDate وعدد قيم OrderID الذي يُعين له الاسم (أو الاسم المستعار)الأوامر:

SELECT OrderDate, COUNT(OrderID) AS Orders

تحدد جملة FROM الجدول المصدر لصفوف الاستعلام؛ في هذه الحالة يكون الجدول Sales.SalesOrder:

FROM Sales.SalesOrder

يتم من خلال جملة WHERE تصفية الصفوف من النتائج والاحتفاظ فقط بتلك الصفوف التي تفي بالشرط المحدد؛ في هذه الحالة، الطلبات التي لها الحالة "shipped":

WHERE Status = 'Shipped'

تأخذ عبارة «GROUP BY» الصفوف التي تفي بشرط عامل التصفية وتجمِّعها حسب OrderDate، بحيث يتم اعتبار كل الصفوف ذات نفس OrderDate كمجموعة واحدة، وسيتم إرجاع صف واحد لكل مجموعة:

GROUP BY OrderDate

بعد تشكيل المجموعات، تقوم جملة HAVING بتصفية المجموعات وفقًا لتخمينها الخاص. سيتم تضمين التواريخ التي تحتوي على أكثر من طلب واحد فقط في النتائج:

HAVING COUNT(OrderID) > 1

لأغراض معاينة هذا الاستعلام، العبارة النهائية هي ORDER BY، التي يتم من خلالها فرز الإخراج إلى ترتيب OrderDate التنازلي:

ORDER BY OrderDate DESC;

الآن بعد أن رأيت ما تفعله كل جملة، دعونا ننظر إلى الترتيب تقييم SQL Server لها بالفعل:

  1. يتم تقييم جملة FROM أولاً، وذلك لتوفير صفوف المصدر لبقية العبارة. يتم إنشاء جدول ظاهري وتمريره إلى الخطوة التالية.
  2. جملة WHERE هي التالية في التقييم، حيث تتم تصفية تلك الصفوف من الجدول المصدر التي تطابق التخمين. يتم تمرير الجدول الظاهري الذي تمت تصفيته إلى الخطوة التالية.
  3. GROUP BY هي التالية، حيث يتم تنظيم الصفوف في الجدول الظاهري وفقًا لقيم فريدة موجودة في القائمة GROUP BY. يتم إنشاء جدول ظاهري جديد، يحتوي على قائمة المجموعات، ويتم تمريره إلى الخطوة التالية. من هذه النقطة في تدفق العمليات، يمكن الإشارة إلى الأعمدة فقط في قائمة GROUP BY أو الوظيفة التجميعية بواسطة عناصر أخرى.
  4. يتم تقييم جملة HAVING بعد هذا، يحث تتم تصفية مجموعات بأكملها استنادًا إلى تخمينها الخاص. تتم تصفية الجدول الظاهري الذي تم إنشاؤه في الخطوة 3 وتمريره إلى الخطوة التالية.
  5. في النهاية يتم تنفيذ جملة SELECT، حيث يتم تحديد الأعمدة التي ستظهر في نتائج الاستعلام. نظرًا لأنه يتم تقييم جملة SELECT بعد الخطوات الأخرى، لا يمكن استخدام أي أسماء مستعارة للعمود (في المثال، الطلبات) التي تم إنشاؤها في جملة GROUP BY أو HAVING.
  6. جملة ORDER BY هي آخر ما يتم تنفيذه، حيث يتم فرز الصفوف كما تحددها قائمة الأعمدة بها.

لتطبيق هذا الفهم على استعلام المثال لدينا، إليك الترتيب المنطقي في وقت تشغيل لعبارة SELECT أعلاه:

FROM Sales.SalesOrder
WHERE Status = 'Shipped'
GROUP BY OrderDate 
HAVING COUNT(OrderID) > 1
SELECT OrderDate, COUNT(OrderID) AS Orders
ORDER BY OrderDate DESC;

ليس كل العبارات المحتملة مطلوبة في كل عبارة SELECT تكتبها. العبارة المطلوبة الوحيدة هي عبارة SELECT، التي يمكن استخدامها من تلقاء نفسها في بعض الحالات. عادة ما يتم تضمين جملة FROM أيضًا لتحديد الجدول الذي يتم الاستعلام عنه. بالإضافة إلى ذلك، لدى Transact-SQL جمل أخرى يمكن إضافتها.

كما رأيت، لا تكتب استعلامات T-SQL بنفس الترتيب الذي يتم تقييمها منطقيًا. يحدد ترتيب وقت التشغيل للتقييم أي البيانات تتوفر لأي جُمل، حيث إن الجملة لديها فقط إمكانية الوصول إلى المعلومات المتوفرة بالفعل من جملة تمت معالجتها بالفعل. لهذا السبب، من المهم فهم ترتيب المعالجة المنطقي الحقيقي عند كتابة الاستعلامات.

تحديد كل الأعمدة

غالبًا ما يُشار إلى جملة SELECT باسم قائمة SELECT، لأنها تسرد القيم التي سيتم إرجاعها في نتائج الاستعلام.

أبسط شكل من جملة SELECT هو استخدام حرف النجمة (*) لإرجاع كل الأعمدة. عند استخدامها في استعلامات T-SQL، تسمى نجمة. بينما SELECT * مناسبة لاختبار سريع، يجب تجنب استخدامه في أعمال الإنتاج للأسباب التالية:

  • سوف تنعكس التغييرات على الجدول الذي يضيف أعمدة أو يعيد ترتيبها في نتائج الاستعلام، مما قد يؤدي إلى إخراج غير متوقع للتطبيقات أو التقارير التي تستخدم الاستعلام.
  • يمكن أن يؤدي إرجاع بيانات غير مطلوبة إلى إبطاء استعلاماتك ويتسبب في مشاكل في الأداء إذا كان الجدول المصدر يحتوي على عدد كبير من الصفوف.

على سبيل المثال، يتم من خلال المثال التالي استرداد كل الأعمدة من الجدول Production.Product (افتراضي).

SELECT * FROM Production.Product;

النتيجة من هذا الاستعلام هي مجموعة الصفوف التي تحتوي على كل الأعمدة لكل صفوف الجدول، والتي قد تبدو مثل هذا:

معرّف المنتج

الاسم

ProductNum

Color

التكلفة القياسية «StandardCost»

ListPrice

الحجم

الوزن

ProductCatID

680

إطار طريق HL - أسود، 58

FR-R92B-58

أسود

1059.31

1431.5

58

1016.04

18

706

إطار طريق HL - أحمر، 58

FR-R92R-58

أحمر

1059.31

1431.5

58

1016.04

18

707

خوذة Sport-100, أحمر

HL-U509-R

أحمر

13.0863

34.99

35

708

خوذة Sport-100, أسود

HL-U509

أسود

13.0863

34.99

35

...

...

...

...

...

...

...

...

...

تحديد أعمدة محددة

تسمح لك قائمة الأعمدة الصريحة بالتحكم في الأعمدة التي يتم إرجاعها بالضبط وفي أي ترتيب. سيكون لكل عمود في النتيجة اسم العمود كرأس.

على سبيل المثال، خذ بعين الاعتبار الاستعلام التالي؛ الذي يستخدم مرة أخرى الجدول Production.Product الافتراضي.

SELECT ProductID, Name, ListPrice, StandardCost
‎FROM Production.Product;

هذه المرة، تتضمن النتائج الأعمدة المحددة فقط:

معرّف المنتج

الاسم

ListPrice

التكلفة القياسية «StandardCost»

680

إطار طريق HL - أسود، 58

1431.5

1059.31

706

إطار طريق HL - أحمر، 58

1431.5

1059.31

707

خوذة Sport-100, أحمر

34.99

13.0863

708

خوذة Sport-100, أسود

34.99

13.0863

...

...

...

...

تحديد التعبيرات

بالإضافة إلى استرداد الأعمدة المخزنة في الجدول المحدد، يمكن لعبارة SELECT إجراء العمليات الحسابية والتلاعب، والتي تستخدم عوامل التشغيل لدمج الأعمدة والقيم أو أعمدة متعددة. يجب أن تكون نتيجة الحساب أو المعالجة نتيجة ذات قيمة مفردة (دالة) ستظهر في النتيجة كأعمدة منفصلة.

على سبيل المثال، يتضمن الاستعلام التالي تعبيرين:

SELECT ProductID,
      Name + '(' + ProductNumber + ')',
  ListPrice - StandardCost
FROM Production.Product;

قد تبدو نتائج هذا الاستعلام على النحو التالي:

معرّف المنتج

680

إطار طريق HL - أسود، 58 (FR-R92B-58)

372.19

706

إطار طريق HL - أحمر، 58 (FR-R92R-58)

372.19

707

خوذة رياضية 100 ، أحمر (HL-U509-R)

21.9037

708

خوذة رياضية 100 ، أسود (HL-U509)

21.9037

...

...

...

هناك بعض الأشياء المثيرة للاهتمام التي تجب ملاحظتها حول هذه النتائج:

  • الأعمدة التي تم إرجاعها بواسطة التعبيرين ليس لها أسماء أعمدة. استنادًا إلى الأداة التي تستخدمها لإرسال استعلامك، قد تتم الإشارة إلى اسم عمود مفقود بواسطة رأس عمود فارغ أو مؤشر يفيد حرفيًا "no column name" أو اسم افتراضي مثل column1. سنرى كيفية تحديد اسم مستعار لاسم العمود في الاستعلام لاحقًا في هذا القسم.
  • يستخدم التعبير الأول عامل التشغيل + لإنشاء سلسلة القيم (المستندة إلى حرف)، بينما يستخدم التعبير الثاني عامل التشغيل - لطرح قيمة رقمية واحدة من أخرى. عند استخدامه مع القيم الرقمية، ينفذ عامل التشغيل + إضافة. ومن الواضح أنه من المهم فهم أنواع بيانات للأعمدة التي تضمنها في التعبيرات. سنناقش أنواع البيانات في القسم التالي.

تحديد الأسماء المستعارة للعمود

يمكنك تحديد اسم مستعار لكل عمود يتم إرجاعه بواسطة استعلام SELECT، إما كبديل لاسم العمود المصدر أو لتعيين اسم لإخراج تعبير.

على سبيل المثال، إليك نفس الاستعلام كما كان من قبل، ولكن مع اتحديد لأسماء المستعارة لكل عمود من الأعمدة:

SELECT ProductID AS ID,
      Name + '(' + ProductNumber + ')' AS ProductName,
  ListPrice - StandardCost AS Markup
FROM Production.Product;

تتضمن نتائج هذا الاستعلام أسماء الأعمدة المحددة:

بطاقة تعريف

ProductName

رفع السعر

680

إطار طريق HL - أسود، 58 (FR-R92B-58)

372.19

706

إطار طريق HL - أحمر، 58 (FR-R92R-58)

372.19

707

خوذة رياضية 100 ، أحمر (HL-U509-R)

21.9037

708

خوذة رياضية 100 ، أسود (HL-U509)

21.9037

...

...

...

إشعار

الكلمة الأساسية AS اختيارية عند تحديد اسم مستعار، ولكن من الجيد تضمينها للتوضيح.

استعلامات التنسيق

قد تلاحظ من الأمثلة في هذا القسم أنه يمكنك أن تكون مرنًا حيال كيفية تنسيق التعليمات البرمجية للاستعلام. على سبيل المثال، يمكنك كتابة كل جملة (أو الاستعلام بأكمله) في سطر واحد، أو تقسيمها على أسطر متعددة. في معظم أنظمة قاعدة البيانات، تكون التعليمة البرمجية غير حساسة لحالة الأحرف، وبعض عناصر لغة T-SQL اختيارية (بما في ذلك الكلمة الأساسية AS كما ذكر سابقًا، وحتى علامة الفاصلة المنقوطة في نهاية عبارة).

راجع الإرشادات التالية لجعل تعليمة T-SQL البرمجية سهلة القراءة (وبالتالي أسهل في الفهم والتصحيح!):

  • اكتب كلمات T-SQL الأساسية بأحرف كبيرة، مثل SELECT وFROM وAS وهكذا. تعتبر كتابة الكلمات الأساسية بأحرف كبيرة اصطلاح شائع الاستخدام يسهل العثور على كل جملة من عبارات معقدة.
  • ابدأ سطرًا جديدًا لكل جملة رئيسية من عبارة.
  • إذا كانت قائمة SELECT تحتوي على أكثر من بضعة أعمدة أو تعبيرات أو أسماء مستعارة، ففكر في سرد كل عمود في سطره الخاص.
  • تحتوي سطور المسافة البادئة على جُمل فرعية أو أعمدة لتوضيح التعليمات البرمجية التي تنتمي لكل جملة رئيسية.