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

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

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

  • التوابع الشرطية للنطاق والتي تستخدم عامل BETWEEN.
  • والتوابع الشرطية لعضوية المجموعة التي تستخدم عامل IN.

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

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

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

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

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

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

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

$ ssh ssh user@your_server_ip

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

$ mysql -u user -p

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

mysql> CREATE DATABASE between_in_db;

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

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

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

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

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

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

  • name: أسماء أعضاء فريق المبيعات، معبرًا عنها باستخدام نمط البيانات varchar بحد أقصى 20 محرفًا.
  • widgets: العدد الإجمالي للأجهزة الصغيرة التي باعها كل بائع، معبرًا عنها بنمط بيانات الأعداد الصحيحة int.
  • doodads: عدد الأدوات المتنوعة التي باعها كل بائع، معبرًا عنها أيضًا بنمط بيانات الأعداد الصحيحة int.
  • gizmos: عدد الأجهزة المبتكرة التي باعها كل بائع، معبرًا عنها أيضًا بنمط بيانات الأعداد الصحيحة int.

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

mysql> CREATE TABLE sales (
mysql> name varchar(20),
mysql> widgets int,
mysql> doodads int,
mysql> gizmos int
mysql> );
الخرج
Query OK, 0 rows affected (0.01 sec)

الآن سنملأ جدول sales بعض البيانات التجريبية. نفّذ العملية INSERT INTO التالية لإضافة سبع سجلات من البيانات تمثل أعضاء فريق المبيعات وعدد ما باعوه من كل منتج:

mysql> INSERT INTO sales
mysql> VALUES
mysql> ('Tyler', 12, 22, 18),
mysql> ('Blair', 19, 8, 13),
mysql> ('Lynn', 7, 29, 3),
mysql> ('Boris', 16, 16, 15),
mysql> ('Lisa', 17, 2, 31),
mysql> ('Maya', 5, 9, 7),
mysql> ('Henry', 14, 2, 0);

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

فهم التوابع الشرطية الخاصة ببنية WHERE

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

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

ومن الجدير بالملاحظة أنّه في معظم الأحيان نستخدم على الأقل اسم عمود من الجدول المُشار إليه ضمن بنية FROM من العملية كأحد تعابير القيمة في التابع الشرطي ضمن بنية WHERE

ولدى تشغيل استعلامات SQL المُتضمّنة لبنية WHERE، سيطبق نظام إدارة قاعدة البيانات (DBMS) شرط البحث على كل سجل في الجدول المنطقي المحدد في بنية FROM ليُعيد فقط السجلات التي يُقيّم من أجلها كل تابع شرطي في شرط البحث على أنه "محقق TRUE".

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

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

  • =: يختبر ما إذا كانت القيمتان متساويتين.
  • <>: يختبر ما إذا كانت القيمتان غير متساويتين.
  • <: يختبر ما إذا كانت القيمة الأولى أقل من الثانية.
  • >: يختبر ما إذا كانت القيمة الأولى أكبر من الثانية.
  • <=: يختبر ما إذا كانت القيمة الأولى أقل من أو تساوي الثانية.
  • >=: يختبر ما إذا كانت القيمة الأولى أكبر من أو تساوي الثانية.

القيم الفارغة: تختبر التوابع الشرطية التي تستخدم عامل IS NULL ما إذا كانت القيم في عمود معين فارغة.

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

العضوية: يستخدم هذا النوع من التوابع الشرطية عامل IN لاختبار ما إذا كانت قيمة ما تُمثّل عضوًا في مجموعة معينة.

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

وكما ذكرنا في المقدمة، يركز هذا المقال على توضيح كيفية استخدام عوامل BETWEEN وIN في SQL لتصفية البيانات. فإذا كنت ترغب في معرفة كيفية استخدام عوامل المقارنة أو عامل IS NULL، ننصحك بقراءة مقالنا حول كيفية استخدام عوامل المقارنة وIS NULL في لغة الاستعلام البنيوية SQL. أمّا إذا كنت ترغب في معرفة كيفية استخدام عامل LIKE لتصفية البيانات بناءً على نمط نصي يحتوي على محارف بدل، فننصحك بقراءة المقال كيفية استخدام محارف البدل في SQL. وللاطلاع على المزيد حول بنى WHERE عمومًا، ننصحك بقراءة مقالنا حول كيفية استخدام بنى WHERE في لغة الاستعلام البنيوية SQL.

التوابع الشرطية النطاقية

تستخدم التوابع الشرطية النطاقية عامل BETWEEN لاختبار ما إذا كان تعبير قيمة محصور بين تعبيري قيمة آخرين. وتتبع بنية WHERE المُتضمنة لتابع شرطي نطاقي في شرط البحث الخاص بها الصيغة العامة التالية:

mysql> SELECT column_list
mysql> FROM table_name
mysql> WHERE column_name BETWEEN value_expression1 AND value_expression2;

ويأتي بعد كلمة WHERE المفتاحية تعبير قيمة، والذي يكون في معظم عمليات SQL عبارة عن اسم عمود. وبما أن نظام قاعدة البيانات يطبق شروط البحث على كل سجل تباعًا، فإن توفير اسم عمود كتعبير قيمة في شرط البحث يخبر نظام إدارة قواعد البيانات العلاقية RDBMS باستخدام قيمة كل سجل من العمود المحدد كجزء من تعبير القيمة للتكرار الخاص بكل سجل في شرط البحث.

ويأتي بعد اسم العمود عامل BETWEEN وتعبيري قيمة آخرين مفصولين بعامل AND. وسيُقيّم شرط البحث على أنه "صحيح True" لأي سجلات تكون قيمتها في العمود المحدد أكبر من أو تساوي القيمة الأولى من القيمتين المفصولتين بعامل AND وأقل من أو تساوي القيمة الثانية.

لتوضيح كيفية عمل التوابع الشرطية النطاقية، لننفّذ الاستعلام التالي. والذي سيُعيد قيم عمودي name وwidgets لأي سجلات تكون فيها قيمة widgets محصورة بين 14 و19ضمنًا:

mysql> SELECT name, widgets
mysql> FROM sales
mysql> WHERE widgets BETWEEN 14 AND 19;
الخرج
+-------+---------+
| name  | widgets |
+-------+---------+
| Blair |      19 |
| Boris |      16 |
| Lisa  |      17 |
| Henry |      14 |
+-------+---------+
4 rows in set (0.00 sec)

تذكر أن النطاق الذي تحدده بعد عامل BETWEEN يمكن أن يتكون من أي زوج من تعابير القيمة، بما في ذلك أسماء الأعمدة.

يعيد الاستعلام التالي جميع الأعمدة من جدول sales. وفيه، وبدلًا من تحديد كل عمود على حدة، ألحقنا الكلمة المفتاحية SELECT بعلامة النجمة (*) مباشرةً، وهي الطريقة المختصرة في SQL للإشارة إلى "جميع الأعمدة". وتحدّ بنية WHERE في هذا الاستعلام من إرجاعه للسجلات التي تكون فيها قيمة gizmos أكبر من قيمة doodads لكنها أقل من قيمة widgets:

mysql> SELECT *
mysql> FROM sales
mysql> WHERE gizmos BETWEEN doodads AND widgets;

لا يمتلك سوى عضو واحد من فريق المبيعات قيمة في عمود gizmos محصورة بين القيمتين widgets وdoodads. لذا فإنّ السجل الخاص به فقط هو الذي يظهر في مجموعة النتائج.

الخرج
+-------+---------+---------+--------+
| name  | widgets | doodads | gizmos |
+-------+---------+---------+--------+
| Blair |      19 |       8 |     13 |
+-------+---------+---------+--------+
1 row in set (0.00 sec)

ويجب أن تكون على دراية بترتيب تعابير القيمة المُحدّدة للنطاق: فالقيمة الأولى بعد عامل BETWEEN تُمثّل دائمًا الحد الأدنى للنطاق، أمّا القيمة الثانية فتُمثّل الحد الأعلى. الاستعلام التالي مطابق للسابق، باستثناء أنه يعكس ترتيب الأعمدة التي تُحدد طرفيّ النطاق:

mysql> SELECT *
mysql> FROM sales
mysql> WHERE gizmos BETWEEN widgets AND doodads;

يعيد الاستعلام هذه المرة سجلين حيث تكون في كل منهما قيمة gizmos أكبر من أو تساوي قيمة widgets للسجل ولكنها أقل من أو تساوي قيمة doodads. وكما تدل النتائج، يمكن أن يؤدي تغيير الترتيب بهذه الطريقة إلى استرجاع مجموعة نتائج مختلفة تمامًا.

الخرج
+-------+---------+---------+--------+
| name  | widgets | doodads | gizmos |
+-------+---------+---------+--------+
| Tyler |      12 |      22 |     18 |
| Maya  |       5 |       9 |      7 |
+-------+---------+---------+--------+
2 rows in set (0.00 sec)

وعلى نحوٍ مشابه لحالة استخدام عوامل المقارنة <، >، <=، و >= لتقييم عمود مُتضمّن لقيم من نمط السلاسل النصية، سيُحدد العامل BETWEEN ما إذا كانت هذه القيم تقع أبجديًا بين قيمتين من نمط السلاسل النصية.

لتوضيح الفكرة، لنُنفّذ الاستعلام التالي الذي يعيد قيم العمود name الموافقة لأي سجل من الجدول sales حيث تكون قيمة name محصورة أبجديَا بين الحرفين A و M.

استخدمنا في هذا المثال سلسلتين نصيتين مجردتين كتعبيريّ قيمة يمثلان طرفي النطاق. ومن الجدير بالملاحظة أنّه يجب حصر هذه القيم المحرفية بين علامات اقتباس مفردة أو مزدوجة، وإلا سيبحث نظام إدارة قواعد البيانات عن أعمدة باسم A و M، مما قد يؤدي إلى فشل الاستعلام.

mysql> SELECT name
mysql> FROM sales
mysql> WHERE name BETWEEN 'A' AND 'M';
الخرج
+-------+
| name  |
+-------+
| Blair |
| Lynn  |
| Boris |
| Lisa  |
| Henry |
+-------+
5 rows in set (0.00 sec)

نلاحظ أن مجموعة النتائج هذه لا تتضمن الاسم Maya رغم كون النطاق المحدد في شرط البحث يمتد من A إلى M. السبب في ذلك هو أن الحرف M يأتي أبجديًا قبل أي سلسلة نصية تبدأ بالحرف M وتحتوي على أكثر من حرف، لذا يُستثنى الاسم Maya من مجموعة النتائج هذه، بالإضافة إلى أي بائعين آخرين لا تقع أسماؤهم ضمن النطاق المحدد.

التوابع الشرطية للعضوية

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

mysql>. . .
mysql> WHERE column_name IN (set_of_data)
mysql>. . .

يأتي بعد الكلمة المفتاحية WHERE تعبير القيمة، وعادةً ما يكون هذا التعبير عبارة عن اسم عمود. يلي ذلك عامل IN، الذي يُتبع بدوره بمجموعة من البيانات. يمكن تحديد هذه المجموعة بوضوح عن طريق إدراج أي عدد من تعابير القيمة الصالحة مفصولةً بعلامات فاصلة، سواء كانت قيمًا مجردة أو أسماء أعمدة أو تعابير رياضية تتضمن أيًا من العناصر آنفة الذكر.

لتوضيح الأمر، لنُنفذ الاستعلام التالي. والذي سيعيد قيم عموديّ name وgizmos لكل سجل تُمثّل فيه قيمة gizmos عضوًا من المجموعة المعرّفة بعد عامل IN:

mysql> SELECT name, doodads
mysql> FROM sales
mysql> WHERE doodads IN (1, 2, 11, 12, 21, 22);

نلاحظ أن قيم العمود doodads لثلاثة أعضاء فقط من فريق المبيعات تساوي أي من القيم الموجودة ضمن هذه المجموعة، ولذلك فإن السجلات الخاصة بهم فقط هي المُسترجعة.

الخرج
+-------+---------+
| name  | doodads |
+-------+---------+
| Tyler |      22 |
| Lisa  |       2 |
| Henry |       2 |
+-------+---------+
3 rows in set (0.00 sec)

وبدلًا من كتابة كل عنصر في مجموعة بنفسك، يُمكنك تكوين مجموعة من خلال إلحاق عامل IN بالاستعلام الفرعي. يُعرف الاستعلام الفرعي أيضًا بالاستعلام المُدمج أو الداخلي، وهو تعليمة SELECT مُدرجة ضمن إحدى بنى تعليمة SELECT أخرى. يُمكن للاستعلام الفرعي أن يستخرج المعلومات من أي جدول ضمن نفس قاعدة البيانات المحددة في بنية FROM للعملية الرئيسة 'الخارجية'.

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

كمثال على استخدام الاستعلام الفرعي لتحديد مجموعة في تابع شرطي للعضوية، نفذ التعليمة التالية لإنشاء جدول يُسمى example_set_table يحتوي على عمود واحد فقط. سنسمى هذا العمود prime_numbers وسيحتوي على قيم من نمط البيانات int، على النحو:

mysql> CREATE TABLE example_set_table (
mysql> prime_numbers int
mysql> );

لنملأ الآن هذا الجدول ببضعة سجلات من البيانات التجريبية النموذجية. وفقًا لاسم العمود الوحيد في الجدول، ستُضيف التعليمة INSERT التالية عشرة سجلات إلى الجدول، ويحتوي كل منها على أحد الأعداد الأولية العشرة الأولى:

mysql>INSERT INTO example_set_table
mysql>VALUES
mysql> (2),
mysql> (3),
mysql> (5),
mysql> (7),
mysql> (11),
mysql> (13),
mysql> (17),
mysql> (19),
mysql> (23),
mysql> (29);

لنُشغّل الآن الاستعلام التالي الذي يُعيد قيمًا من أعمدة name و widgets في جدول sales، إذ تختبر بنية WHERE ما إذا كانت كل قيمة في عمود widgets تنتمي للمجموعة التي حصلنا عليها من الاستعلام الفرعي SELECT prime_numbers FROM example_set_table:

mysql> SELECT name, widgets
mysql> FROM sales
mysql> WHERE widgets IN (SELECT prime_numbers FROM example_set_table);
الخرج
+-------+---------+
| name  | widgets |
+-------+---------+
| Blair |      19 |
| Lynn  |       7 |
| Lisa  |      17 |
| Maya  |       5 |
+-------+---------+
4 rows in set (0.00 sec)

بما أنّ أربعة فقط من أعضاء فريق المبيعات باعوا عددًا من الأجهزة الصغيرة يُطابق أحد الأعداد الأولية الموجودة في جدول example_set_table، سيُعيد هذا الاستعلام تلك السجلات الأربعة فقط.

الخلاصة

باطلاعك على هذا المقال، ستكون قد اكتسبت المعرفة حول كيفية استخدام العامل BETWEEN في SQL لتحديد ما إذا كانت قيم في عمود ما تندرج ضمن نطاق محدد، كما تعلمت كيفية استخدام عامل IN لتحديد ما إذا كانت قيم في عمود ما تنتمي إلى مجموعة معينة.

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

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

ترجمة -وبتصرف- للمقال How To Use the BETWEEN and IN Operators 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.


×
×
  • أضف...