طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 121 · مبادئ قواعد البيانات
الدرس 15 · الوحدة 7: استرجاع وتحليل البيانات

الاسترجاع: SELECT و WHERE

نختار الأعمدة التي نحتاجها، والصفوف التي تحقق شروطنا. ⏱ نحو 25 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تختار الأعمدة وتحسب أعمدة جديدة وتسمّيها بـ AS.
  • تصفّي الصفوف بـ WHERE وأدوات المقارنة.
  • تدمج الشروط بـ AND و OR و NOT مع الأقواس.
  • تشرح ترتيب تنفيذ الاستعلام.

١اختيار الأعمدة

SELECT أكثر أوامر SQL استخدامًا: يقرأ البيانات ولا يغيّرها أبدًا. بعده الأعمدة التي نريدها بالترتيب الذي نريده، و * لكل الأعمدة:

query.sql
SELECT name, price, category FROM products;
النتيجة · 12 صفًّا
namepricecategory
قهوة عربية 250غ35مشروبات
شاي أخضر18مشروبات
تمر عجوة 1كغ90تمور
تمر سكري 1كغ45تمور
عسل سدر 500غ150عسل
عسل زهور 500غ60عسل
دلة قهوة75أدوات
فناجين (6 قطع)40أدوات
هيل 100غ28بهارات
زعفران 5غ55بهارات
ماء زمزم 5لتر12مشروبات
مبخرة120أدوات

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

يمكن أن يكون العمود عملية حسابية، ونعطيه اسمًا مستعارًا بالكلمة AS:

query.sql
SELECT name,       price,       ROUND(price * 1.15, 2) AS price_with_vat,       price * stock         AS stock_valueFROM products;
النتيجة · 12 صفًّا
namepriceprice_with_vatstock_value
قهوة عربية 250غ3540.251400
شاي أخضر1820.71170
تمر عجوة 1كغ90103.52250
تمر سكري 1كغ4551.750
عسل سدر 500غ150172.51800
عسل زهور 500غ60691800
دلة قهوة7586.25600
فناجين (6 قطع)4046800
هيل 100غ2832.21400
زعفران 5غ5563.25825
ماء زمزم 5لتر1213.81200
مبخرة120138600

ROUND(x, 2) تقرّب الناتج إلى منزلتين عشريتين؛ فالحساب العشري في الحاسب قد يعطي 40.24999999 بدل 40.25.

ولدمج النصوص نستخدم || في SQLite. وفي MySQL الدالة CONCAT(a, ' - ', b):

query.sql
SELECT name || ' (' || category || ')' AS labelFROM products;
النتيجة · 12 صفًّا
label
قهوة عربية 250غ (مشروبات)
شاي أخضر (مشروبات)
تمر عجوة 1كغ (تمور)
تمر سكري 1كغ (تمور)
عسل سدر 500غ (عسل)
عسل زهور 500غ (عسل)
دلة قهوة (أدوات)
فناجين (6 قطع) (أدوات)
هيل 100غ (بهارات)
زعفران 5غ (بهارات)
ماء زمزم 5لتر (مشروبات)
مبخرة (أدوات)

٣تصفية الصفوف: WHERE

WHERE تختار الصفوف التي تحقق شرطًا. وأدوات المقارنة:

المعاملمعناهمثال
=يساويcity = 'جدة'
<> أو !=لا يساويstatus <> 'ملغى'
> <أكبر، أصغرprice > 50
>= <=أكبر أو يساوي، أصغر أو يساويorder_date >= '2025-04-01'
query.sql
SELECT name, priceFROM productsWHERE price > 50;
النتيجة · 6 صفوف
nameprice
تمر عجوة 1كغ90
عسل سدر 500غ150
عسل زهور 500غ60
دلة قهوة75
زعفران 5غ55
مبخرة120
query.sql
SELECT id, order_date, statusFROM ordersWHERE order_date >= '2025-04-01';
النتيجة · 6 صفوف
idorder_datestatus
72025-04-01قيد الشحن
82025-04-09قيد الشحن
92025-04-20جديد
102025-05-03جديد
112025-05-07جديد
122025-05-12جديد

التواريخ بصيغة YYYY-MM-DD تُقارن كالنصوص بشكل صحيح، لأن السنة ثم الشهر ثم اليوم.

٤دمج الشروط: AND و OR و NOT

المعاملالصف يظهر إذا…
ANDتحقق الشرطان معًا
ORتحقق أحدهما على الأقل
NOTلم يتحقق الشرط
query.sql
-- مشروبات سعرها أقل من 20SELECT name, category, priceFROM productsWHERE category = 'مشروبات' AND price < 20;
النتيجة · صفّان
namecategoryprice
شاي أخضرمشروبات18
ماء زمزم 5لترمشروبات12

انتبه: AND تُنفَّذ قبل OR، مثل الضرب قبل الجمع. هنا نريد «العسل والتمور التي سعرها فوق 80»:

✗ خطأ
query.sql
SELECT name, category, priceFROM productsWHERE category = 'عسل' OR category = 'تمور'  AND price > 80;
النتيجة · 3 صفوف
namecategoryprice
تمر عجوة 1كغتمور90
عسل سدر 500غعسل150
عسل زهور 500غعسل60
✓ صواب
query.sql
SELECT name, category, priceFROM productsWHERE (category = 'عسل' OR category = 'تمور')  AND price > 80;
النتيجة · صفّان
namecategoryprice
تمر عجوة 1كغتمور90
عسل سدر 500غعسل150

بلا أقواس، فُهم الشرط: «كل العسل» أو «التمور فوق 80»، فظهر عسل الزهور بـ 60. الأقواس تحدد ما تريده بالضبط.

٥كيف يقرأ النظام الاستعلام؟

نكتب SELECT أولًا، لكن النظام ينفّذ بترتيب آخر:

  1. FROM: من أي جدول؟
  2. WHERE: أي الصفوف تبقى؟
  3. SELECT: أي الأعمدة تُعرض؟
query.sql
SELECT name, ROUND(price * 1.15, 2) AS price_vatFROM productsWHERE price_vat > 100;
النتيجة · 3 صفوف
nameprice_vat
تمر عجوة 1كغ103.5
عسل سدر 500غ172.5
مبخرة138

في SQLite يعمل هذا لأنه متساهل. لكن في MySQL والمعيار يفشل: WHERE تُنفَّذ قبل SELECT، فلا تعرف الاسم المستعار price_vat بعد. اكتب الحساب نفسه: WHERE price * 1.15 > 100.

🧪 ملعب SQLجرّب: عملاء الرياض، والطلبات الجديدة (status)، والمنتجات التي نفدت (stock = 0).

توقّع وتحقّق

لا يساوي في SQL:

أو !=

أي يُنفَّذ أولًا؟

ثم WHERE ثم SELECT.

AND أم OR تُنفَّذ أولًا؟

استخدم الأقواس.

لتسمية العمود المحسوب:

اسم مستعار.

الخلاصة

تحدٍّ برمجي: عروض الشتاء

متوسط

قسم التسويق يجهز عرضًا على المشروبات والبهارات التي سعرها 30 ريالًا أو أقل، ويريد السعر بعد خصم 10%.

المطلوب:
  • اعرض: اسم المنتج name، والسعر price، والسعر بعد الخصم باسم offer_price.
  • المنتجات من تصنيف «مشروبات» أو «بهارات» فقط، وسعرها 30 أو أقل.
👀 اعرض النتيجة المطلوبة
النتيجة المطلوبة
namepriceoffer_price
شاي أخضر1816.2
هيل 100غ2825.2
ماء زمزم 5لتر1210.8
✓ التحقق الآلي من حلّك:
  • الكود يعمل بلا أخطاء
  • النتيجة فيها المنتجات الثلاثة الصحيحة بالأعمدة الثلاثة
  • تستخدم الاسم المستعار offer_price

💡 تلميح 1
الخصم 10%: السعر × 0.9
💡 تلميح 2
لا تنسَ الأقواس حول شرطي التصنيف.

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

solution.sql
SELECT name, price, price * 0.9 AS offer_priceFROM productsWHERE (category = 'مشروبات' OR category = 'بهارات')  AND price <= 30;
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس