جملة SELECT المتقدمة (Advanced SELECT)

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

1. DISTINCT: إزالة القيم المكررة

في كثير من الأحيان، قد تحتوي البيانات على قيم مكررة. على سبيل المثال، إذا كان لديك جدول طلاب وتريد معرفة المدن التي يسكن فيها الطلاب، قد تجد نفس المدينة مكررة عدة مرات. الكلمة المفتاحية DISTINCT تُستخدم لإرجاع قيم فريدة فقط (بدون تكرار).

مثال: جدول الطلاب
جدول students
+----+-----------+-----+--------+
| id | name      | age | city   |
+----+-----------+-----+--------+
| 1  | أحمد      | 20  | الرياض |
| 2  | فاطمة     | 19  | جدة    |
| 3  | محمد      | 21  | الرياض |
| 4  | سارة      | 20  | مكة    |
| 5  | علي       | 22  | جدة    |
| 6  | نورة      | 19  | الرياض |
+----+-----------+-----+--------+
بدون DISTINCT: قائمة بها تكرار
استعلام بدون DISTINCT
SELECT city FROM students;
النتيجة (بها تكرار)
+--------+
| city   |
+--------+
| الرياض |  ← مكررة
| جدة    |
| الرياض |  ← مكررة
| مكة    |
| جدة    |  ← مكررة
| الرياض |  ← مكررة
+--------+
6 rows in set
مع DISTINCT: قيم فريدة فقط
استعلام مع DISTINCT
SELECT DISTINCT city FROM students;
النتيجة (بدون تكرار)
+--------+
| city   |
+--------+
| الرياض |
| جدة    |
| مكة    |
+--------+
3 rows in set

لاحظ أن النتيجة الآن تحتوي على 3 صفوف فقط بدلاً من 6، وكل مدينة تظهر مرة واحدة فقط!

DISTINCT مع عدة أعمدة

يمكنك استخدام DISTINCT مع عدة أعمدة. في هذه الحالة، سيُرجع الاستعلام التركيبات الفريدة من هذه الأعمدة:

DISTINCT مع عمودين
SELECT DISTINCT age, city FROM students;
النتيجة
+-----+--------+
| age | city   |
+-----+--------+
| 20  | الرياض |
| 19  | جدة    |
| 21  | الرياض |
| 20  | مكة    |
| 22  | جدة    |
| 19  | الرياض |
+-----+--------+

هنا، كل صف يمثل تركيبة فريدة من العمر والمدينة. مثلاً، (20, الرياض) تختلف عن (21, الرياض).

نصيحة: استخدم DISTINCT عندما تريد معرفة القيم الفريدة في عمود أو مجموعة أعمدة، مثل "ما هي الأقسام الموجودة في الشركة؟" أو "ما هي الدول التي لدينا عملاء فيها؟"

2. AS: إعادة تسمية الأعمدة (Aliases)

الكلمة المفتاحية AS تُستخدم لإعطاء اسم مؤقت (Alias) لعمود أو جدول في نتيجة الاستعلام. هذا مفيد جداً لجعل النتائج أكثر وضوحاً، خاصة عند استخدام عمليات حسابية أو دوال.

البنية الأساسية
صيغة AS
SELECT column_name AS alias_name
FROM table_name;
مثال 1: إعادة تسمية عمود واحد

لنفترض أن لدينا جدول منتجات:

جدول products
+----+------------------+--------+
| id | name             | price  |
+----+------------------+--------+
| 1  | لابتوب Dell      | 3500   |
| 2  | ماوس لاسلكي      | 50     |
| 3  | لوحة مفاتيح      | 120    |
+----+------------------+--------+
استخدام AS لتسمية أوضح
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 اختيارية! يمكنك كتابة الاسم المستعار مباشرة بعد اسم العمود:

بدون كلمة 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: حساب السعر بعد الضريبة
حساب السعر مع ضريبة 15%
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: حساب الخصم
حساب السعر بعد خصم 20%
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: عمليات متعددة

لنفترض أن لدينا جدول طلبات:

جدول orders
+----+------------------+-------+----------+
| 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
جدول employees
+----+------------+-----------+
| 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. استخدم أسماء مستعارة ذات معنى

اختر أسماء مستعارة واضحة تصف البيانات:

أسماء جيدة vs سيئة
-- سيء: غير واضح
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) وتطوير مهاراتك في قواعد البيانات.

الانتقال إلى الدرس التالي
المحرر الذكي

اكتب الكود وشاهد النتيجة فوراً

جرب الآن مجاناً
قناة ديف عربي

تابع أحدث الدروس والتحديثات مباشرة على واتساب

انضم الآن