اذهب إلى المحتوى

كيفية استخدام بنى WHERE في لغة الاستعلام البنيوية SQL


محمد الخضور

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

وبالرغم من أننا سنستخدم في أمثلتنا بهذا المقال تعليمات SELECT على وجه التحديد، إلّا أنّه من الممكن استخدام المفاهيم الموضحة فيه في العديد من عمليات SQL، إذ يمكن استخدام بنية WHERE كذلك في عمليات تحديث البيانات UPDATE أو حذفها DELETE.

مستلزمات العمل

لمتابعة الخطوات في هذا المقال، ستحتاج إلى جهاز كمبيوتر يُشغّل أحد أنواع أنظمة إدارة قواعد البيانات العلاقية التي تستخدم لغة SQL. وقد اختبرنا الأوامر البرمجية والأمثلة في هذا المقال مستخدمين البيئة التالية:

  • خادم عامل على توزيعة أوبنتو، مع مستخدم ذو صلاحيات مسؤول مختلف عن المستخدم الجذر، وجدار حماية مكوّن باستخدام UFW، كما هو موضح في مقال كيفية تثبيت توزيعة أوبنتو من لينكس بأبسط طريقة.
  • MySQL مثبتة ومؤمنة على الخادم، كما هو موضح في المقال كيفية تثبيت MySQL على أوبونتو. وقد نفذنا خطوات هذا المقال باستخدام مستخدم MySQL مختلف عن المستخدم الجذر، مُنشأ وفق الطريقة الموضحة في الخطوة الثالثة من هذا المقال.
  • ستحتاج أيضًا إلى قاعدة بيانات بجداول مُحمّلة ببعض البيانات التجريبية النموذجية لتتمكن من التدرب على كتابة استعلامات تتضمّن بنى WHERE. لذا ننصحك بقراءة الفقرة التالية التي تشرح طريقة الاتصال بـ MySQL وإعداد قاعدة بيانات تجريبية نموذجية للمزيد من التفاصيل حول تنفيذ الأمثلة المُستخدمة خلال هذا المقال.

ملاحظة: تجدر الإشارة إلى أنّ الكثير من أنظمة إدارة قواعد البيانات العلاقية لها تقديماتها الفريدة من لغة SQL، فبالرغم من كون الأوامر المُقدمة في هذا المقال ستعمل مع معظم هذه الأنظمة، ولكن قد تجد بعض الاختلافات الطفيفة في الصيغة أو الخرج عند تنفيذها على أنظمة مختلفة عن MySQL.

الاتصال بـ MySQL وإعداد قاعدة بيانات تجريبية نموذجية

إذا كان نظام قاعدة بيانات SQL الخاص بك يعمل على خادم عن بُعد، اتصل بالخادم مُستخدمًا بروتوكول SSH من جهازك المحلي على النحو التالي:

$ ssh ssh user@your_server_ip

ثم افتح واجهة سطر الأوامر في خادم MySQL، مُستبدلًا user باسم حساب مستخدم MySQL الخاص بك:

$ mysql -u user -p

الآن ومن نافذة سطر الأوامر، أنشئ قاعدة بيانات باسم where_db كما يلي:

mysql> CREATE DATABASE where_db;

بمجرّد إنشاء قاعدة البيانات بنجاح ستحصل على خرجٍ كالتالي:

الخرج
Query OK, 1 row affected (0.01 sec)

ولاختيار قاعدة البيانات where_db، نفّذ تعليمة USE التالية:

mysql> USE where_db;
الخرج
Database changed

بعد اختيار قاعدة البيانات where_db، أنشئ جدولًا ضمنها.

ولمتابعة الأمثلة المستخدمة في هذا المقال، سنفترض أننا نرغب بإدارة دوري للغولف في ملعب غولف محلي. وقررنا تتبع المعلومات حول أداء كل لاعب في الدوري خلال الجولات التي سيشارك بها، لذا قررنا تخزين المعلومات في قاعدة بيانات تتضمن جدولًا باسم golfers.

وارتأينا أنّ هذا الجدول يحتاج إلى ستة أعمدة وهي:

  • name: أسماء لاعبي الغولف، مُعبر عنها باستخدام نمط البيانات varchar بحد أقصى 20 محرفًا.
  • rounds_played: إجمالي عدد الجولات التي لعبها كل لاعب غولف كاملةً، مُعبر عنها بنمط بيانات الأعداد الصحيحة int.
  • best: أفضل أو أدنى نتيجة لكل لاعب جولف لجولة فردية، مُعبرًا عنها أيضًا بنمط الأعداد الصحيحة int.
  • worst: أسوأ أو أعلى نتيجة لكل لاعب جولف لجولة فردية، مُعبرًا عنها كذلك بنمط الأعداد الصحيحة int.
  • average: متوسط تقريبي لنتائج كل لاعب غولف عبر الجولات التي لعبوها، سيحتوي هذا العمود على قيم من نوع decimal، محددة بحد أقصى 4 أرقام، واحد منها على يمين الفاصلة العشرية.
  • wins: عدد الجولات التي حقق فيها كل لاعب غولف أقل نتيجة بين جميع المشاركين في المجموعة، مُعبر عنها باستخدام نمط int.

ملاحظة: قد تستغرب لماذا تكون النتيجة الأفضل best لكل لاعب أدنى من نتيجته الأسوأ worst، وهذا يعود لطبيعة قواعد لعبة الغولف التي تقتضي أن يكون الفائز هو من ينجز اللعبة بأقل عدد من الضربات. بالتالي، وبخلاف الرياضات الأخرى، تُعد النتيجة الأدنى هي الأفضل للاعب الغولف.

لإنشاء جدول باسم golfers يحتوي على هذه الأعمدة الستة، نفّذ التعليمة CREATE TABLE التالية:

mysql> CREATE TABLE golfers (
mysql> name varchar(20),
mysql> rounds_played int,
mysql> best int,
mysql> worst int,
mysql> average decimal (4,1),
mysql> wins int
mysql> );

الآن سنملأ جدول golfers ببعض البيانات التجريبية. نفّذ العملية INSERT INTO التالية لإضافة سبع سجلات من البيانات تمثل سبعة من لاعبي الدوري للغولف:

mysql> INSERT INTO golfers
mysql> VALUES
mysql> ('George', 22, 68, 103, 84.6, 3),
mysql> ('Pat', 25, 65, 74, 68.7, 9),
mysql> ('Grady', 11, 78, 118, 97.6, 0),
mysql> ('Diane', 23, 70, 92, 78.8, 1),
mysql> ('Calvin', NULL, 63, 76, 68.5, 7),
mysql> ('Rose', NULL, 69, 84, 76.7, 4),
mysql> ('Raymond', 18, 67, 92, 81.3, 1);

نلاحظ أن قيم rounds_played لبعض سجلات اللاعبين فارغة NULL. فلنفترض جدلًا أنّ هؤلاء اللاعبين لم يُبلغوا بعد عن عدد الجولات التي شاركوا فيها، ولهذا السبب سُجلت هذه القيم على أنّها فارغة NULL.

وبذلك غدوتَ جاهزًا للمتابعة بباقي أقسام المقال وبدء تعلم كيفية استخدام بنى WHERE في SQL.

تصفية البيانات باستخدام بنى WHERE

تُعرّف التعليمة البرمجية في SQL بأنّها أي عملية تُرسَل إلى نظام قاعدة البيانات لتنفيذ مهمّة محددة، من قبيل إنشاء جدول أو إدخال أو حذف بيانات أو تغيير هيكلية عمود أو جدول. وتتألف تعليمات SQL من بنى مختلفة تتكون بدورها من كلمات مفتاحية معينة مع المعلومات التي تتطلبها هذه الكلمات.

وكما ذكرنا في المقدمة، تتيح بنى WHERE إمكانية تصفية بعض السجلات كي لا تتأثر بعملية SQL محددة. وتأتي بنية WHERE في الاستعلامات، بعد بنية FROM، كما في المثال التالي:

mysql> SELECT columns_to_query
mysql> FROM table_to_query
mysql> WHERE search_condition;

يأتي شرط البحث بعد كلمة WHERE المفتاحية. وما شرط البحث سوى مجموعة من التوابع الشرطية أو التعبيرات القادرة على تقييم تعبير قيمة واحد أو أكثر لتعيد نتيجة تكون إمّا "صحيحة True" أو "خاطئة False" أو "غير محددة Unknown"، ومن الجدير بالملاحظة أنّه في الحالات التي يحتوي فيها شرط البحث على تابع شرطي واحد فقط، يكون المصطلحان "شرط البحث" و"التابع الشرطي" مترادفين.

قد تأخذ التوابع الشرطية في شرط البحث الخاص ببنية WHERE أشكالًا عديدة، لكنها عادةً ما تتبع الصيغة التالية:

WHERE column_name OPERATOR value_expression

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

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

لتوضيح هذه الفكرة، شغّل الاستعلام التالي. والذي سيعيد كل قيمة من العمود name في الجدول golfers:

mysql> SELECT name
mysql> FROM golfers
mysql> WHERE (2 + 2) = 4;

يتضمن هذا الاستعلام بنية WHERE، لكن بدلًا من تحديد اسم عمود فإنها تستخدم (2 + 2) كتعبير قيمة أول وتختبر ما إذا كان مساويًا لتعبير القيمة الثاني 4. ونظرًا لأنّ التعبير (2 + 2) يساوي دائمًا 4، فإن شرط البحث هذا يُقيّم على أنه صحيح لكل سجل في الجدول. ونتيجةً لذلك، تُرجع قبم كافّة السجلات في مجموعة النتائج، على النحو التالي:

الخرج
+---------+
| name    |
+---------+
| George  |
| Pat     |
| Grady   |
| Diane   |
| Calvin  |
| Rose    |
| Raymond |
+---------+
7 rows in set (0.01 sec)

لعلّ بنية WHERE هذه ليست مفيدة بدرجة كبيرة، إذ إنها تُقيم دائمًا على أنها "صحيحة True" وبالتالي تُرجع دائمًا كافة سجلات الجدول. وكما ذكرنا سابقًا، عادةً ما نستخدم اسم عمود واحد على الأقل كأحد تعبيري القيمة في شرط البحث ضمن بنية WHERE. فلدى تشغيل الاستعلامات، سيطبق نظام قاعدة البيانات شرط البحث على كل سجل على حدة تباعًا. ومن خلال توفير اسم عمود كتعبير قيمة في شرط بحث، فإنك تُخبر نظام إدارة قاعدة البيانات باستخدام قيمة كل سجل من العمود المحدد كجزء من تعبير القيمة للتكرار الخاص بكل سجل في شرط البحث.

تُطبّق بنية WHERE في الاستعلام التالي شرط بحث أكثر تحديدًا على كل سجل. إذ ستُرجع قيم كل من عمودي name وwins من أي سجل تساوي فيه
قيمة wins الرقم 1:

mysql> SELECT name, wins
mysql> FROM golfers
mysql> WHERE wins = 1;

يُرجع هذا الاستعلام سجليّن للاعبي جولف، نظرًا لوجود لاعبين قد فازا بجولة واحدة فقط، فيكون الخرج على هذا النحو:

الخرج
+---------+------+
| name    | wins |
+---------+------+
| Diane   |    1 |
| Raymond |    1 |
+---------+------+
2 rows in set (0.01 sec)

من الجدير بالملاحظة أنّنا استخدمنا في الأمثلة السابقة علامة المساواة = لاختبار ما إذا كان تعبيرا القيمة متكافئين، إلا أنّ العامل المُستخدم يعتمد على نوع التابع الشرطي الذي ترغب باستخدامه لتصفية مجموعات النتائج الخاصة بك. يُحدّد معيار SQL ثمانية عشر نمطًا مختلفًا من التوابع الشرطية، على الرغم من أنّها لا تتوفر كاملةً في كافّة تقديمات SQL. إليك خمسة من أكثر أنماط التوابع الشرطية استخدامًا، بالإضافة إلى شرح موجز لكل منها والعوامل المستخدمة فيها:

المقارنة

تقارن التوابع الشرطية المقارنِة بين تعبيري قيمة باستخدام عامل مقارنة، وفي معظم الاستعلامات يكون أحد هذين التعبيرين هو اسم عمود. وعوامل المقارنة الستة هي:

  • العامل =: يختبر ما إذا كانت القيمتان متساويتين
mysql> SELECT name
mysql> FROM golfers
mysql> WHERE name = 'George';
الخرج
+--------+
| name   |
+--------+
| George |
+--------+
1 row in set (0.00 sec)
  • العامل <>: يختبر ما إذا كانت القيمتان غير متساويتين
mysql> SELECT name, wins
mysql> FROM golfers
mysql> WHERE wins <> 1;
الخرج
+--------+------+
| name   | wins |
+--------+------+
| George |    3 |
| Pat    |    9 |
| Grady  |    0 |
| Calvin |    7 |
| Rose   |    4 |
+--------+------+
5 rows in set (0.00 sec)
  • العامل <: يختبر ما إذا كانت القيمة الأولى أقل من الثانية تمامًا
mysql> SELECT name, wins
mysql> FROM golfers
mysql> WHERE wins < 1;
الخرج
+-------+------+
| name  | wins |
+-------+------+
| Grady |    0 |
+-------+------+
1 row in set (0.00 sec)
  • العامل >: يختبر ما إذا كانت القيمة الأولى أكبر من الثانية تمامًا
mysql> SELECT name, wins
mysql> FROM golfers
mysql> WHERE wins > 1;
الخرج
+--------+------+
| name   | wins |
+--------+------+
| George |    3 |
| Pat    |    9 |
| Calvin |    7 |
| Rose   |    4 |
+--------+------+
4 rows in set (0.00 sec)
  • العامل <=: يختبر ما إذا كانت القيمة الأولى أقل من أو تساوي الثانية
mysql> SELECT name, wins
mysql> FROM golfers
mysql> WHERE wins <= 1;
الخرج
+---------+------+
| name    | wins |
+---------+------+
| Grady   |    0 |
| Diane   |    1 |
| Raymond |    1 |
+---------+------+
3 rows in set (0.00 sec)
  • العامل >=: يختبر ما إذا كانت القيمة الأولى أكبر من أو تساوي القيمة الثانية
mysql> SELECT name, wins
mysql> FROM golfers
mysql> WHERE wins >= 1;
الخرج
+---------+------+
| name    | wins |
+---------+------+
| George  |    3 |
| Pat     |    9 |
| Diane   |    1 |
| Calvin  |    7 |
| Rose    |    4 |
| Raymond |    1 |
+---------+------+
6 rows in set (0.00 sec)

القيم الفارغة

تختبر التوابع الشرطية التي تستخدم عامل IS NULL ما إذا كانت القيم في عمود معين فارغة، فإذا كان الأمر كذلك فعلًا، سيقيّم التابع الشرطي على أنه "صحيح"، وبالتالي سيُضمّن السجل في مجموعة النتائج:

mysql> SELECT name, rounds_played
mysql> FROM golfers
mysql> WHERE rounds_played IS NULL;
الخرج
+--------+---------------+
| name   | rounds_played |
+--------+---------------+
| Calvin |          NULL |
| Rose   |          NULL |
+--------+---------------+
2 rows in set (0.00 sec)

النطاق

تستخدم التوابع الشرطية النطاقية عامل BETWEEN لاختبار ما إذا كانت قيم العمود محصورة بين تعبيري قيمة آخرين.

mysql> SELECT name, best
mysql> FROM golfers
mysql> WHERE best BETWEEN 67 AND 73;
الخرج
+---------+------+
| name    | best |
+---------+------+
| George  |   68 |
| Diane   |   70 |
| Rose    |   69 |
| Raymond |   67 |
+---------+------+
4 rows in set (0.00 sec)

الانتماء أو العضوية

يستخدم هذا النوع من التوابع الشرطية عامل IN لاختبار ما إذا كانت قيمة ما تنتمي لمجموعة معينة.

mysql> SELECT name, best
mysql> FROM golfers
mysql> WHERE best IN (65, 67, 69, 71);
الخرج
+---------+------+
| name    | best |
+---------+------+
| Pat     |   65 |
| Rose    |   69 |
| Raymond |   67 |
+---------+------+
3 rows in set (0.00 sec)

تطابق الأنماط

تستخدم توابع مطابقة الأنماط الشرطية عامل LIKE لاختبار ما إذا كانت قيمة ما تطابق نمطًا نصيًا يحتوي على محرف بدل واحد أو أكثر. وتُعرّف SQL محرفي بدل
هما % و _:

  • محرف _: شرطة سفلية تُمثّل محرفًا واحدًا مجهولًا
mysql> SELECT name, rounds_played
mysql> FROM golfers
mysql> WHERE rounds_played LIKE '2_';
الخرج
+--------+---------------+
| name   | rounds_played |
+--------+---------------+
| George |            22 |
| Pat    |            25 |
| Diane  |            23 |
+--------+---------------+
3 rows in set (0.00 sec)
  • محرف %: علامة النسبة المئوية تُمثّل صفر أو أكثر من المحارف المجهولة
mysql> SELECT name, rounds_played
mysql> FROM golfers
mysql> WHERE name LIKE 'G%';
الخرج
+--------+---------------+
| name   | rounds_played |
+--------+---------------+
| George |            22 |
| Grady  |            11 |
+--------+---------------+
2 rows in set (0.00 sec)

لن نفصّل بشرح كل نمط من التوابع الشرطية فهو خارج مجال هذا المقال، ولمعرفة المزيد حول هذه الأنماط، ننصحك بالاطلاع على المقالات التالية:

  • كيفية استخدام عوامل المقارنة وIS NULL في لغة الاستعلام البنيوية SQL
  • كيفية استخدام عوامل BETWEEN وIN في لغة الاستعلام البنيوية SQL
  • كيفية استخدام محارف البدل في SQL

دمج التوابع الشرطية المتعددة باستخدام عوامل AND وOR

قد نضطر في الكثير من الأحيان إلى تصفية النتائج على نحوٍ أدق مما توفره بنية WHERE ذات تابع شرطي وحيد. ومن ناحيةٍ أخرى، قد تكون السجلات التي تحقق واحدًا من شروط بحث متعددة مقبولة ضمن مجموعة النتائج في بعض الأحيان. وفي هذه الحالات، يمكنك كتابة بنى WHERE تتضمن توابع شرطية متعددة باستخدام عوامل AND أو OR على التوالي.

للبدء باستخدام هذه العوامل، لنشغّل الاستعلام التالي الذي يعيد قيم من أعمدة name وbest وworst وaverage في جدول golfers. إذ تتضمن بنية WHERE الخاصة بهذا الاستعلام تابعين شرطيين مفصولين بعامل AND:

mysql> SELECT name, best, worst, average
mysql> FROM golfers
mysql> WHERE best < 70 AND worst < 96;

يختبر التابع الشرطي الأول ما إذا كانت أفضل قيمة (قيمة العمود best) لكل سجل تقل عن 70، في حين يختبر التابع الشرطي الثاني ما إذا كانت أسوأ قيمة (قيمة العمود worst) لكل سجل تقل عن 96. الآن وفي حال تقييم أي من الشرطين على أنه "خاطئ False" لسجل ما، فإنّ هذا السجل لن يُعاد ضمن مجموعة النتائج:

الخرج
+---------+------+-------+---------+
| name    | best | worst | average |
+---------+------+-------+---------+
| Pat     |   65 |    74 |    68.7 |
| Calvin  |   63 |    76 |    68.5 |
| Rose    |   69 |    84 |    76.7 |
| Raymond |   67 |    92 |    81.3 |
+---------+------+-------+---------+
4 rows in set (0.00 sec)

الآن، لنشغّل الاستعلام التالي، وهو كما تلاحظ مطابق للمثال السابق، باستثناء فصل التابعين الشرطيين بعامل OR بدلًا من AND:

mysql> SELECT name, best, worst, average
mysql> FROM golfers
mysql> WHERE best < 70 OR worst < 96;

نلاحظ أنّ مجموعة النتائج في هذا المثال تتضمّن سجلين أكثر من المثال السابق، وذلك نظرًا لأنّه مع استخدام عامل OR يكفي تقييم تابع شرطي واحد على أنّه "صحيح True" للسجل لكي يُعاد ضمن مجموعة النتائج:

الخرج
+---------+------+-------+---------+
| name    | best | worst | average |
+---------+------+-------+---------+
| George  |   68 |   103 |    84.6 |
| Pat     |   65 |    74 |    68.7 |
| Diane   |   70 |    92 |    78.8 |
| Calvin  |   63 |    76 |    68.5 |
| Rose    |   69 |    84 |    76.7 |
| Raymond |   67 |    92 |    81.3 |
+---------+------+-------+---------+
6 rows in set (0.00 sec)

يمكنك إدراج العديد من التوابع الشرطية في بنية WHERE واحدة بشرط دمجها باستخدام الصياغة المناسبة. ولكن قد يصعب تنبؤ بالبيانات التي ستُصفى مع زيادة تعقيد شروط البحث.

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

لتوضيح ذلك، شغّل الاستعلام التالي الذي يسترجع قيمًا من أعمدة name وaverage وworst وrounds_played لكل سجل يستوفي شروط البحث المحددة في بنية WHERE:

mysql> SELECT name, average, worst, rounds_played
mysql> FROM golfers 
mysql> WHERE average < 85 OR worst < 95 AND rounds_played BETWEEN 19 AND 23;

يبدأ هذا الاستعلام باختبار ما إذا كان كلا التابعين الشرطيين (worst < 95 و rounds_played BETWEEN 19 AND 23) المفصولين بعامل AND يقيمان على أنهما محققان  بالنسبة للسجل قيد الاختبار الحالي. فإذا كان الأمر كذلك، سيظهر هذا السجل ضمن مجموعة النتائج.

أمّا إذا قُيّم أحدهما أو كلاهما على أنه غير محقق "false"، فسينتقل الاستعلام لفحص ما إذا كانت قيمة average للصف الحالي أقل من 85. وفي حال كانت كذلك، سيظهر الصف ضمن مجموعة النتائج.

الخرج
+---------+---------+-------+---------------+
| name    | average | worst | rounds_played |
+---------+---------+-------+---------------+
| George  |    84.6 |   103 |            22 |
| Pat     |    68.7 |    74 |            25 |
| Diane   |    78.8 |    92 |            23 |
| Calvin  |    68.5 |    76 |          NULL |
| Rose    |    76.7 |    84 |          NULL |
| Raymond |    81.3 |    92 |            18 |
+---------+---------+-------+---------------+
6 rows in set (0.00 sec)

يمكنك منح الأولوية لمجموعة من تابعين شرطيين فأكثر بوضعهم داخل أقواس. المثال التالي يطابق المثال السابق، لكنه يضع التابعين الشرطيين average < 85 وworst < 95، المفصولين بعامل OR، ضمن أقواس.

mysql> SELECT name, average, worst, rounds_played
mysql> FROM golfers
mysql> WHERE (average < 85 OR worst < 95) AND rounds_played BETWEEN 19 AND 23;

نظرًا لأن التابعين الشرطيين في البداية مُحاطين بأقواس، فيعاملهما عامل AND الذي يليهما كشرط بحث مستقل، والذي يجب أن يُقيّم على أنه محقق “True”. فإذا قُيّم كلا التابعين الشرطيين (average < 85 وworst < 95) على أنهما غير محققين “false”، فسيُعتبر شرط البحث بأكمله غير محقق “False” وبالتالي سيستبعد الاستعلام هذا السجل من مجموعة النتائج على الفور قبل أن ينتقل لتقييم السجل التالي.

أمّا إذا قُيّم أي من التابعين الشرطيين بين القوسين على أنه محقق “True”، فيبدأ الاستعلام حينها في اختبار ما إذا كانت قيمة rounds_played للاعب الجولف تقع ضمن النطاق 19 و 23. وفي حال تحقق ذلك، يُضم السجل إلى مجموعة النتائج المُعادة.

الخرج
+--------+---------+-------+---------------+
| name   | average | worst | rounds_played |
+--------+---------+-------+---------------+
| George |    84.6 |   103 |            22 |
| Diane  |    78.8 |    92 |            23 |
+--------+---------+-------+---------------+
2 rows in set (0.00 sec)

كما تُظهر هذه النتائج، بإعطاء الأولوية لمجموعات التوابع الشرطية وضمها ضمن أقواس، يمكن أن تُنتج الاستعلامات المتشابهة ظاهريًا مجموعات نتائج متباينة بدرجة كبيرة.

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

استثناء النتائج باستخدام عامل NOT

ركّزت جميع الأمثلة في هذا المقال حتى الآن على كيفية كتابة استعلامات باستخدام بنية WHERE، والتي تُضمّن فقط السجلات التي تُحقّق شروط البحث المُحددة في مجموعة النتائج. ولكن يُمكنك كتابة استعلامات تستثني سجلات مُحددة عبر إدراج عامل NOT ضمن بنية WHERE.

وعادةً ما تتبع بنى التوابع الشرطية للنطاق والعضوية وتطابق الأنماط التي تشمل عامل NOT الصياغة العامة التالية:

mysql> . . .
mysql> WHERE column_name NOT OPERATOR value_expression
mysql> . . .

للتوضيح، شغّل الاستعلام التالي الذي سيعيد قيمًا من عمود name في جدول golfers، ولكن وجود عامل NOT في بنية WHERE سيُلزم نظام إدارة قاعدة البيانات باستثناء أي سجلات تُطابق نمط محرف البدل:

mysql> SELECT name
mysql> FROM golfers
mysql> WHERE name NOT LIKE 'R%';
الخرج
+--------+
| name   |
+--------+
| George |
| Pat    |
| Grady  |
| Diane  |
| Calvin |
+--------+
5 rows in set (0.00 sec)

تتغير الأمور قليلًا عند إضافة عامل NOT إلى توابع IS NULL الشرطية. في هذه الحالات، يُدرج العامل NOT بين IS وNULL كما في المثال التالي. يُعيد هذا الاستعلام قيم name وrounds_played لجميع لاعبي الغولف الذين لا تكون قيمة rounds_played الخاصة بهم فارغة، على النحو:

mysql> SELECT name, rounds_played
mysql> FROM golfers
mysql> WHERE rounds_played IS NOT NULL;
الخرج
+---------+---------------+
| name    | rounds_played |
+---------+---------------+
| George  |            22 |
| Pat     |            25 |
| Grady   |            11 |
| Diane   |            23 |
| Raymond |            18 |
+---------+---------------+
5 rows in set (0.00 sec)

كما يُمكنك وضع عامل NOT مباشرةً بعد الكلمة المفتاحية WHERE. الأمر الذي يعدّ مفيدًا لا سيما في حال رغبتك باستثناء سجلات بناءً على ما إذا كانت تحقق عدة شروط بحث، كما في الاستعلام التالي الذي يعيد قيم كل من أعمدة name و average و best و wins للاعبي الغولف.

mysql> SELECT name, average, best, wins
mysql> FROM golfers
mysql> WHERE NOT (average < 80 AND best < 70) OR wins = 9;
الخرج
+---------+---------+------+------+
| name    | average | best | wins |
+---------+---------+------+------+
| George  |    84.6 |   68 |    3 |
| Pat     |    68.7 |   65 |    9 |
| Grady   |    97.6 |   78 |    0 |
| Diane   |    78.8 |   70 |    1 |
| Raymond |    81.3 |   67 |    1 |
+---------+---------+------+------+
5 rows in set (0.00 sec)

بالنظر إلى السجل الثاني من مجموعة النتائج أعلاه، نلاحظ أنّ متوسط نتيجة اللاعبة Pat في العمود average أقل من 80 وأفضل نتيجة لها في العمود best أقل من 70. ومع ذلك سجلها مُضمّن في مجموعة النتائج، وذلك نظرًا لأن عامل NOT يُلغي فقط شروط البحث المُحاطة بالأقواس.

تذكر أنه عند إحاطة توابع شرطية متعددة مفصولة بعوامل AND أو OR بأقواس، تُعطى الأولوية لهذه التوابع في SQL وتُعامل كشرط بحث مستقل. بالتالي، يستثني عامل NOT السجلات بناءً على أول تابعي شرط فقط (average<80 و best<70). في حين تُضمّن السجلات بناءً على التابع الشرطي الثالث (wins=9).

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

mysql> SELECT name, average, best, wins
mysql> FROM golfers
mysql> WHERE NOT ((average < 80 AND best < 70) OR wins = 9);
الخرج
+---------+---------+------+------+
| name    | average | best | wins |
+---------+---------+------+------+
| George  |    84.6 |   68 |    3 |
| Grady   |    97.6 |   78 |    0 |
| Diane   |    78.8 |   70 |    1 |
| Raymond |    81.3 |   67 |    1 |
+---------+---------+------+------+
4 rows in set (0.00 sec)

قد يعدّ نظام قاعدة البيانات لديك صيغة الاستعلام غير صالحة في حال تضمين العامل NOT قبل عامل مقارنة وذلك تبعًا لتقديم SQL المُستخدم. كمثال، لنجرب تشغيل الاستعلام التالي:

mysql> SELECT name
mysql> FROM golfers
mysql> WHERE name NOT = 'Grady';

سيؤدي استخدام هذا الأمر في MySQL أو أي من الأنظمة المستندة إليها إلى حدوث خطأ.

الخرج
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '= 'Grady'' at line 1

السبب وراء هذا الخطأ هو أنّ عامل NOT لا يُستخدم عادةً مع عوامل المقارنة (= و<> و< و<= و> و>=)، وذلك نظرًا لإمكانية تحقيق الأثر المعاكس لعامل مقارنة معيّن باستبداله بآخر يعيد السجلات التي كان الأول سيستثنيها. على سبيل المثال، يمكنك استبدال عامل المساواة (=) بعامل عدم المساواة (<>).

الخلاصة

باطلاعك على هذا المقال،تكون قد اكتسبت المعرفة حول كيفية كتابة بنى WHERE بطريقة تجعل الاستعلام يُعيد فقط السجلات التي تستوفي شرطًا معينًا. كما تعلمت كيفية دمج عدّة توابع شرطية وشروط بحث في استعلام واحد، ناهيك عن كيفية استخدام العامل NOT لاستثناء معلومات من مجموعات النتائج.

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

وللمزيد حول SQL، نشجعك على متابعة المقالات المنشورة تحت وسم سلسلة تعلم SQL في أكاديمية حسوب.

ترجمة -وبتصرف- للمقال How To Use WHERE Clauses in SQL لصاحبه Mark Drake.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...