📘 وش هي الاستعلامات المتداخلة؟
الاستعلامات المتداخلة هي أوامر SELECT-FROM-WHERE كاملة تكون داخل استعلام SQL ثاني. تسمح لك تستخدم ناتج استعلام كجزء من استعلام آخر.
💡 مشكلة: خطوتين مقابل خطوة واحدة
المشكلة: عايز تلقى كل ورش العمل اللي يقدمها نفس مقدم ورشة "Robot Operating System".
الطريقة ١: استعلامين منفصلين
SELECT Presenter
FROM Workshop
WHERE Title = 'Robot Operating System';
SELECT *
FROM Workshop
WHERE Presenter = 'Dr. Maram';
الطريقة ٢: استعلام واحد مع Subquery
SELECT *
FROM Workshop
WHERE Presenter = (SELECT Presenter
FROM Workshop
WHERE Title = 'Robot Operating System');
🔑 عامل IN
عامل IN يفحص إذا كانت القيمة موجودة في مجموعة القيم اللي يرجعها الاستعلام الداخلي.
💡 مثال على IN
SELECT DISTINCT Essn
FROM WORKS_ON
WHERE (Pno, Hours) IN (SELECT Pno, Hours
FROM WORKS_ON
WHERE Essn = '123456789');
عوامل المقارنة: ANY و ALL
⚙️ عوامل ANY و ALL
- = ANY (أو SOME): TRUE إذا كانت القيمة تساوي عنصر واحد على الأقل في المجموعة (مثل IN).
- > ANY: TRUE إذا كانت القيمة أكبر من عنصر واحد على الأقل.
- > ALL: TRUE إذا كانت القيمة أكبر من كل العناصر في المجموعة.
- < ALL: TRUE إذا كانت القيمة أصغر من كل العناصر في المجموعة.
💡 مثال على ALL
SELECT Lname, Fname
FROM EMPLOYEE
WHERE Salary > ALL (SELECT Salary
FROM EMPLOYEE
WHERE Dno = 5);
مجموعات صريحة
💡 قيم مجموعة محددة
SELECT DISTINCT Essn
FROM WORKS_ON
WHERE Pno IN (1, 2, 3);
📘 صيغة JOIN
SQL المتقدمة توفر صيغة JOIN صريحة في جملة FROM بدل مجرد سرد الجداول.
INNER JOIN
🔑 INNER JOIN (الافتراضي)
يرجع فقط الصفوف اللي فيها تطابق في الجدولين.
💡 مثال على INNER JOIN
SELECT name, First_name, Last_name
FROM Course JOIN Faculty ON Course.Lecturer_id = Faculty.id;
SELECT name, First_name, Last_name
FROM Course INNER JOIN Faculty ON Course.Lecturer_id = Faculty.id;
LEFT OUTER JOIN
📋 LEFT OUTER JOIN
يرجع كل الصفوف من الجدول الأيسر، حتى لو ما في تطابق في الجدول الأيمن. الصفوف اللي ما لها تطابق تجي بقيم NULL.
💡 مثال على LEFT OUTER JOIN
SELECT name, First_name, Last_name
FROM Course LEFT OUTER JOIN Faculty
ON Course.Lecturer_id = Faculty.id;
RIGHT OUTER JOIN
📋 RIGHT OUTER JOIN
يرجع كل الصفوف من الجدول الأيمن، حتى لو ما في تطابق في الجدول الأيسر.
💡 مثال على RIGHT OUTER JOIN
SELECT name, First_name, Last_name
FROM Course RIGHT OUTER JOIN Faculty
ON Course.Lecturer_id = Faculty.id;
FULL OUTER JOIN
💡 مثال على FULL OUTER JOIN
SELECT name, First_name, Last_name
FROM Course FULL OUTER JOIN Faculty
ON Course.Lecturer_id = Faculty.id;
NATURAL JOIN
🔑 خصائص NATURAL JOIN
- ما نحدد شرط الربط.
- يشتغل تلقائياً على كل الأعمدة اللي تحمل نفس الاسم.
- كل عمود مشترك يظهر مرة وحدة في النتيجة.
💡 مثال على NATURAL JOIN
SELECT Fname, Lname, Address
FROM (EMPLOYEE NATURAL JOIN
(DEPARTMENT AS DEPT (Dname, Dno, Mssn, Msdate)))
WHERE Dname = 'Research';
CROSS JOIN
⚠️ CROSS JOIN (الجداء الديكارتي)
استخدمه بحذر! يرجع كل التركيبات الممكنة من الصفوف.
SELECT *
FROM Table1 CROSS JOIN Table2;
ربط أكثر من جدولين
💡 ربط ٣+ جداول
SELECT Pnumber, Dnum, Lname, Address, Bdate
FROM ((PROJECT JOIN DEPARTMENT ON Dnum = Dnumber)
JOIN EMPLOYEE ON Mgr_ssn = Ssn)
WHERE Plocation = 'Stafford';
📋 تكافؤات أنواع الربط
- LEFT JOIN = LEFT OUTER JOIN
- RIGHT JOIN = RIGHT OUTER JOIN
- FULL JOIN = FULL OUTER JOIN
- INNER JOIN = JOIN
📘 وش هي دوال التجميع؟
دوال التجميع تسوي عمليات حسابية على مجموعة من القيم وترجع قيمة واحدة.
🔑 دوال التجميع الأساسية
| الدالة |
الوصف |
مثال |
| COUNT() |
عدد القيم |
COUNT(*) أو COUNT(DISTINCT A) |
| SUM() |
مجموع القيم |
SUM(Salary) أو SUM(DISTINCT Salary) |
| AVG() |
متوسط القيم |
AVG(GPA) أو AVG(DISTINCT age) |
| MAX() |
أعلى قيمة |
MAX(Salary) |
| MIN() |
أقل قيمة |
MIN(age) |
أمثلة بسيطة على التجميع
💡 تجميع بسيط
SELECT AVG(gpa)
FROM Student;
SELECT MAX(gpa), MIN(gpa)
FROM Student;
SELECT COUNT(DISTINCT department)
FROM Student;
SELECT COUNT(*)
FROM Student;
💡 عدة تجميعات مع بعض
SELECT SUM(Salary), MAX(Salary), MIN(Salary), AVG(Salary)
FROM EMPLOYEE;
SELECT SUM(Salary), MAX(Salary), MIN(Salary), AVG(Salary)
FROM EMPLOYEE JOIN DEPARTMENT ON Dno = Dnumber
WHERE Dname = 'Research';
دوال التجميع في الاستعلامات المتداخلة
💡 تجميع مرتبط
SELECT Lname, Fname
FROM EMPLOYEE
WHERE (SELECT COUNT(*)
FROM DEPENDENT
WHERE Ssn = Essn) >= 2;
📘 وش هو GROUP BY؟
GROUP BY يقسّم البيانات إلى مجموعات بناءً على قيم الخصائص، ثم يطبق دوال التجميع على كل مجموعة بشكل منفصل.
GROUP BY أساسي
💡 أمثلة على التجميع
SELECT Dno, COUNT(*), AVG(Salary)
FROM EMPLOYEE
GROUP BY Dno;
SELECT department, AVG(gpa)
FROM Student
GROUP BY department;
⚠️ قواعد GROUP BY
- ما نقدر نختار في SELECT إلا الخصائص الموجودة في GROUP BY.
- أو نقدر نختار دوال تجميع.
- تأكد إن تقسيمك منطقي لبياناتك.
تجميع بعدة خصائص
💡 تجميع متعدد المستويات
SELECT major, standing, COUNT(*), AVG(age)
FROM Student
GROUP BY major, standing;
GROUP BY مع JOIN
💡 تجميع بعد الربط
SELECT Pnumber, Pname, COUNT(*)
FROM PROJECT, WORKS_ON
WHERE Pnumber = Pno
GROUP BY Pnumber, Pname;
جملة HAVING
🔑 WHERE vs HAVING
- WHERE: يفلتر الصفوف الفردية قبل التجميع.
- HAVING: يفلتر المجموعات بعد التجميع وبعد تطبيق دوال التجميع.
💡 مثال على HAVING
SELECT Pnumber, Pname, COUNT(*)
FROM PROJECT, WORKS_ON
WHERE Pnumber = Pno
GROUP BY Pnumber, Pname
HAVING COUNT(*) > 2;
📋 قيم NULL في GROUP BY
إذا كان عمود التجميع فيه قيم NULL، يتم إنشاء مجموعة مستقلة لكل الصفوف اللي فيها NULL في ذلك العمود.
📘 وش هو الـ View؟
طريقة العرض هي جدول افتراضي يعرض مجموعة فرعية من البيانات من جدول أو أكثر. الـ Views ما تتخزن فعلياً - هي استعلامات تولّد البيانات ديناميكياً لما نستخدمها.
🎯 أغراض الـ Views
- تبسيط الاستعلامات المعقدة: نخفي التعقيد عن المستخدمين.
- الأمان: نحدد الوصول لبيانات معينة.
- التجريد: نعرض البيانات بصيغ محددة.
- التحكم بالدخول: كل مستخدم يشوف بيانات مختلفة.
إنشاء Views
💡 View بسيط
CREATE VIEW EmployeeView AS
SELECT EmployeeID, Name, Position
FROM Employees;
SELECT *
FROM EmployeeView;
💡 View مع JOIN
CREATE VIEW DepartmentEmployeeView AS
SELECT e.Name, d.DepartmentName
FROM Employees e JOIN Departments d
ON e.DepartmentID = d.DepartmentID;
SELECT *
FROM DepartmentEmployeeView;
الـ Views المادية وغير المادية
| الخاصية |
غير مادية (Non-Materialized) |
مادية (Materialized) |
| التخزين |
ما تتخزن فعلياً |
تتخزن كجدول مادي |
| التنفيذ |
الاستعلام ينفذ كل مرة |
البيانات محسوبة مسبقاً |
| حداثة البيانات |
دايمًا محدثة |
تحتاج تحديث دوري |
| الأداء |
أبطأ للاستعلامات المعقدة |
وصول أسرع |
| الأنسب |
للبيانات المتغيرة كثيراً |
للاستعلامات المعقدة على جداول كبيرة |
تحديث Views
⚠️ قيود تحديث الـ View
مو كل الـ Views تقبل التحديث! عشان يكون الـ View قابل للتحديث:
- لازم يرتبط مباشرة ببيانات الجدول الأصلي.
- ما يحتوي على دوال تجميع.
- ما يحتوي على JOIN (في أغلب الأنظمة).
- ما يحتوي على DISTINCT.
الـ Views كوسيلة للتحكم بالدخول
🔒 الأمان مع الـ Views
الـ Views تعطينا تحكم قوي بالدخول عن طريق عرض أعمدة/صفوف محددة لمستخدمين معينين:
CREATE VIEW PublicEmployeeInfo AS
SELECT EmployeeID, Name, Department, Position
FROM Employees;
DROP - حذف كائنات قاعدة البيانات
📘 جملة DROP
أمر DROP يحذف كائنات قاعدة البيانات بشكل نهائي. الكائنات المحذوفة لا يمكن استرجاعها!
⚠️ DROP نهائي!
بمجرد الحذف، الكائنات تُحذف بشكل دائم وما نستعيدها. استخدمه بحذر شديد!
💡 أمثلة على DROP
DROP TABLE tableName;
DROP DATABASE databaseName;
DROP VIEW viewName;
ALTER - تعديل كائنات قاعدة البيانات
📘 جملة ALTER
أمر ALTER يعدل هيكل كائنات قاعدة البيانات الموجودة بدون حذفها.
💡 أمثلة على ALTER
ALTER TABLE tableName
ADD columnName dataType;
ALTER TABLE tableName
MODIFY COLUMN columnName newDataType;
ALTER TABLE tableName
DROP COLUMN columnName;
ALTER TABLE tableName
ADD CONSTRAINT constraint_name
FOREIGN KEY (column) REFERENCES otherTable(column);
🔑 DROP vs ALTER
- DROP: يحذف الكائنات بالكامل بشكل دائم.
- ALTER: يعدل هيكل الكائنات الموجودة.
- كلاهما مهم لتطوير وصيانة قاعدة البيانات.
- كلاهما يحتاج صلاحيات مناسبة.
📘 واجهات برمجة قواعد البيانات (APIs)
- JDBC (Java Database Connectivity): API لتطبيقات Java.
- DB-API: واجهة قياسية لتطبيقات Python.
- كلها تسمح للتطبيقات تتصل، تنفذ استعلامات، تجيب النتائج، وتتعامل مع المعاملات (Transactions).
💡 مثال JDBC (Java)
import java.sql.*;
public class MySQLAccess {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/myDatabase";
String user = "username";
String password = "password";
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connection = DriverManager.getConnection(url, user, password);
Statement statement = connection.createStatement();
String sql = "SELECT id, name FROM employees";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
resultSet.close();
statement.close();
connection.close();
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
🎯 توقعات المشروع
- تنفيذ استعلامات SELECT, INSERT, UPDATE, DELETE في الكود.
- تطبيق منطق أساسي للتطبيق (تسجيل مستخدم، إدارة بيانات).
- مكافأة (+١ درجة اختبار): تنفيذ واجهة رسومية كاملة.
- مكافأة بديلة: ميزات متقدمة (أمان، triggers, deployment).