جملة SELECT المتقدمة (Advanced SELECT)
بعد أن تعلمنا أساسيات جملة SELECT، حان الوقت للتعمق في الميزات المتقدمة التي ستجعل استعلاماتك أكثر قوة ومرونة. في هذا الدرس الشامل، سنتعلم كيفية إزالة القيم المكررة باستخدام DISTINCT، إعادة تسمية الأعمدة باستخدام AS، إجراء عمليات حسابية على البيانات، دمج النصوص، وإنشاء أعمدة محسوبة. ستتعلم أيضاً كيفية جعل نتائج استعلاماتك أكثر وضوحاً واحترافية.
1. DISTINCT: إزالة القيم المكررة
في كثير من الأحيان، قد تحتوي البيانات على قيم مكررة. على سبيل المثال، إذا كان لديك جدول طلاب وتريد معرفة المدن التي يسكن فيها الطلاب، قد تجد نفس المدينة مكررة عدة مرات. الكلمة المفتاحية DISTINCT تُستخدم لإرجاع قيم فريدة فقط (بدون تكرار).
مثال: جدول الطلاب
+----+-----------+-----+--------+
| id | name | age | city |
+----+-----------+-----+--------+
| 1 | أحمد | 20 | الرياض |
| 2 | فاطمة | 19 | جدة |
| 3 | محمد | 21 | الرياض |
| 4 | سارة | 20 | مكة |
| 5 | علي | 22 | جدة |
| 6 | نورة | 19 | الرياض |
+----+-----------+-----+--------+
بدون DISTINCT: قائمة بها تكرار
SELECT city FROM students;
+--------+
| city |
+--------+
| الرياض | ← مكررة
| جدة |
| الرياض | ← مكررة
| مكة |
| جدة | ← مكررة
| الرياض | ← مكررة
+--------+
6 rows in set
مع DISTINCT: قيم فريدة فقط
SELECT DISTINCT city FROM students;
+--------+
| city |
+--------+
| الرياض |
| جدة |
| مكة |
+--------+
3 rows in set
لاحظ أن النتيجة الآن تحتوي على 3 صفوف فقط بدلاً من 6، وكل مدينة تظهر مرة واحدة فقط!
DISTINCT مع عدة أعمدة
يمكنك استخدام DISTINCT مع عدة أعمدة. في هذه الحالة، سيُرجع الاستعلام التركيبات الفريدة من هذه الأعمدة:
SELECT DISTINCT age, city FROM students;
+-----+--------+
| age | city |
+-----+--------+
| 20 | الرياض |
| 19 | جدة |
| 21 | الرياض |
| 20 | مكة |
| 22 | جدة |
| 19 | الرياض |
+-----+--------+
هنا، كل صف يمثل تركيبة فريدة من العمر والمدينة. مثلاً، (20, الرياض) تختلف عن (21, الرياض).
DISTINCT عندما تريد معرفة القيم الفريدة في عمود أو مجموعة أعمدة، مثل "ما هي الأقسام الموجودة في الشركة؟" أو "ما هي الدول التي لدينا عملاء فيها؟"
2. AS: إعادة تسمية الأعمدة (Aliases)
الكلمة المفتاحية AS تُستخدم لإعطاء اسم مؤقت (Alias) لعمود أو جدول في نتيجة الاستعلام. هذا مفيد جداً لجعل النتائج أكثر وضوحاً، خاصة عند استخدام عمليات حسابية أو دوال.
البنية الأساسية
SELECT column_name AS alias_name
FROM table_name;
مثال 1: إعادة تسمية عمود واحد
لنفترض أن لدينا جدول منتجات:
+----+------------------+--------+
| id | name | price |
+----+------------------+--------+
| 1 | لابتوب Dell | 3500 |
| 2 | ماوس لاسلكي | 50 |
| 3 | لوحة مفاتيح | 120 |
+----+------------------+--------+
SELECT
name AS product_name,
price AS product_price
FROM products;
+------------------+---------------+
| product_name | product_price |
+------------------+---------------+
| لابتوب Dell | 3500 |
| ماوس لاسلكي | 50 |
| لوحة مفاتيح | 120 |
+------------------+---------------+
لاحظ أن أسماء الأعمدة في النتيجة تغيرت من name و price إلى product_name و product_price.
مثال 2: AS اختياري
في الواقع، كلمة AS اختيارية! يمكنك كتابة الاسم المستعار مباشرة بعد اسم العمود:
SELECT
name product_name,
price product_price
FROM products;
النتيجة ستكون نفسها تماماً. لكن يُفضل استخدام AS لأنها تجعل الكود أكثر وضوحاً وسهولة في القراءة.
مثال 3: أسماء مستعارة بمسافات
إذا كنت تريد اسماً مستعاراً يحتوي على مسافات أو أحرف خاصة، استخدم علامات الاقتباس:
SELECT
name AS "اسم المنتج",
price AS "السعر بالريال"
FROM products;
+------------------+---------------+
| اسم المنتج | السعر بالريال |
+------------------+---------------+
| لابتوب Dell | 3500 |
| ماوس لاسلكي | 50 |
| لوحة مفاتيح | 120 |
+------------------+---------------+
" أو المفردة ' حسب نظام قاعدة البيانات. MySQL يقبل كليهما، لكن بعض الأنظمة تفضل المزدوجة للأسماء المستعارة.
3. العمليات الحسابية في SELECT
يمكنك إجراء عمليات حسابية مباشرة في جملة SELECT. هذا مفيد جداً لحساب قيم جديدة بناءً على البيانات الموجودة.
العمليات الحسابية الأساسية
+الجمع-الطرح*الضرب/القسمة%الباقي (Modulo)
مثال 1: حساب السعر بعد الضريبة
SELECT
name,
price,
price * 1.15 AS price_with_tax
FROM products;
+------------------+-------+-----------------+
| name | price | price_with_tax |
+------------------+-------+-----------------+
| لابتوب Dell | 3500 | 4025.00 |
| ماوس لاسلكي | 50 | 57.50 |
| لوحة مفاتيح | 120 | 138.00 |
+------------------+-------+-----------------+
شرح: price * 1.15 يعني السعر × 1.15 (أي السعر الأصلي + 15% ضريبة). العمود الجديد price_with_tax هو عمود محسوب، لا يُخزن في قاعدة البيانات، بل يُحسب عند تنفيذ الاستعلام.
مثال 2: حساب الخصم
SELECT
name,
price,
price * 0.20 AS discount_amount,
price - (price * 0.20) AS final_price
FROM products;
+------------------+-------+-----------------+-------------+
| name | price | discount_amount | final_price |
+------------------+-------+-----------------+-------------+
| لابتوب Dell | 3500 | 700.00 | 2800.00 |
| ماوس لاسلكي | 50 | 10.00 | 40.00 |
| لوحة مفاتيح | 120 | 24.00 | 96.00 |
+------------------+-------+-----------------+-------------+
مثال 3: عمليات متعددة
لنفترض أن لدينا جدول طلبات:
+----+------------------+-------+----------+
| id | product | price | quantity |
+----+------------------+-------+----------+
| 1 | لابتوب | 3500 | 2 |
| 2 | ماوس | 50 | 10 |
| 3 | لوحة مفاتيح | 120 | 5 |
+----+------------------+-------+----------+
SELECT
product,
price,
quantity,
price * quantity AS total
FROM orders;
+------------------+-------+----------+-------+
| product | price | quantity | total |
+------------------+-------+----------+-------+
| لابتوب | 3500 | 2 | 7000 |
| ماوس | 50 | 10 | 500 |
| لوحة مفاتيح | 120 | 5 | 600 |
+------------------+-------+----------+-------+
4. دمج النصوص (String Concatenation)
يمكنك دمج عدة أعمدة نصية في عمود واحد باستخدام دوال الدمج. الطريقة تختلف حسب نظام قاعدة البيانات:
في MySQL: استخدام CONCAT
+----+------------+-----------+
| id | first_name | last_name |
+----+------------+-----------+
| 1 | أحمد | محمد |
| 2 | فاطمة | علي |
| 3 | محمد | حسن |
+----+------------+-----------+
SELECT
CONCAT(first_name, ' ', last_name) AS full_name
FROM employees;
+-------------+
| full_name |
+-------------+
| أحمد محمد |
| فاطمة علي |
| محمد حسن |
+-------------+
شرح: CONCAT(first_name, ' ', last_name) يدمج الاسم الأول، مسافة، ثم الاسم الأخير.
في PostgreSQL و SQL Server: استخدام ||
SELECT
first_name || ' ' || last_name AS full_name
FROM employees;
مثال متقدم: تنسيق معلومات الاتصال
SELECT
CONCAT(first_name, ' ', last_name, ' - القسم: ', department) AS employee_info
FROM employees;
+-----------------------------+
| employee_info |
+-----------------------------+
| أحمد محمد - القسم: IT |
| فاطمة علي - القسم: HR |
| محمد حسن - القسم: Sales |
+-----------------------------+
5. أمثلة عملية شاملة
مثال 1: تقرير مبيعات شامل
SELECT
product AS "المنتج",
price AS "السعر",
quantity AS "الكمية",
price * quantity AS "الإجمالي",
(price * quantity) * 0.15 AS "الضريبة",
(price * quantity) * 1.15 AS "الإجمالي مع الضريبة"
FROM orders;
مثال 2: دمج DISTINCT مع AS
SELECT DISTINCT
city AS "المدن المتوفرة"
FROM students
ORDER BY city;
مثال 3: حسابات معقدة
SELECT
CONCAT(first_name, ' ', last_name) AS "الاسم الكامل",
salary AS "الراتب الشهري",
salary * 12 AS "الراتب السنوي",
(salary * 12) / 365 AS "الراتب اليومي"
FROM employees;
6. نصائح وأفضل الممارسات
1. استخدم AS دائماً للعمليات الحسابية
عندما تُجري عملية حسابية، النتيجة ستظهر بعنوان غير واضح مثل price * 1.15. استخدم AS لإعطاء اسم واضح:
-- سيء: غير واضح
SELECT price * 1.15 FROM products;
-- جيد: واضح ومفهوم
SELECT price * 1.15 AS price_with_tax FROM products;
2. DISTINCT يمكن أن يكون بطيئاً
DISTINCT يتطلب من قاعدة البيانات فحص جميع الصفوف وإزالة التكرار، مما قد يكون بطيئاً على الجداول الكبيرة. استخدمه فقط عند الحاجة.
3. انتبه لترتيب العمليات
SQL تتبع ترتيب العمليات الحسابية المعتاد (الضرب والقسمة قبل الجمع والطرح). استخدم الأقواس للوضوح:
-- قد يكون غامضاً
SELECT price + tax * quantity FROM orders;
-- واضح ومحدد
SELECT (price + tax) * quantity FROM orders;
4. استخدم أسماء مستعارة ذات معنى
اختر أسماء مستعارة واضحة تصف البيانات:
-- سيء: غير واضح
SELECT price * 1.15 AS p1 FROM products;
-- جيد: واضح ومفهوم
SELECT price * 1.15 AS price_with_vat FROM products;
ملخص الدرس
- DISTINCT: يُستخدم لإرجاع قيم فريدة فقط (بدون تكرار)
- AS: يُعطي اسماً مؤقتاً (Alias) للأعمدة في النتيجة
- العمليات الحسابية: يمكنك استخدام +، -، *، /، % مباشرة في SELECT
- CONCAT: لدمج النصوص في MySQL (أو || في PostgreSQL)
- الأعمدة المحسوبة: لا تُخزن في قاعدة البيانات، بل تُحسب عند التنفيذ
- Best Practice: استخدم AS دائماً للعمليات الحسابية لجعل النتائج واضحة
الخطوة التالية: جملة WHERE في SQL (WHERE Clause)
أكمل رحلتك التعليمية وانتقل إلى الدرس التالي لتعلم جملة WHERE في (WHERE Clause) وتطوير مهاراتك في قواعد البيانات.
الانتقال إلى الدرس التالي