سنتعرف في مقال اليوم على دور البنية 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.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.