Advanced SQL: Complex Queries & Triggers Advanced SQL: Complex Queries & Triggers

Mastering logic with NULLs, Nested Queries, Joins, Aggregation, and Active Database elements. إتقان المنطق باستخدام NULLs، الاستعلامات المتداخلة، Joins، التجميع، وعناصر Active Database.

NULL & 3-Valued Logic NULL & 3-Valued Logic Nested Queries (IN, EXISTS) Nested Queries (IN, EXISTS) OUTER JOINS OUTER JOINS GROUP BY & HAVING GROUP BY & HAVING Triggers & Assertions Triggers & Assertions

NULLs & 3-Valued Logic NULLs & 3-Valued Logic

In SQL, NULL means "Unknown" or "Not Applicable". Comparisons with NULL do NOT return TRUE or FALSE; they return UNKNOWN. في SQL، تعني NULL "غير معروف" أو "غير قابل للتطبيق". المقارنات مع NULL لا تُرجع TRUE أو FALSE؛ بل تُرجع UNKNOWN.

3-Valued Logic Rules قواعد المنطق ثلاثي القيم (3-Valued Logic)

  • AND:AND: True AND Unknown = Unknown. True AND Unknown = Unknown.
  • OR:OR: True OR Unknown = True. True OR Unknown = True.
  • NOT:NOT: NOT Unknown = Unknown. NOT Unknown = Unknown.

Testing for NULL فحص قيمة NULL

SELECT * FROM EMPLOYEE WHERE Super_ssn IS NULL;

Never use "= NULL". It will always fail. لا تستخدم "= NULL" أبداً. ستفشل دائماً.

Nested Queries Nested Queries (الاستعلامات المتداخلة)

Uncorrelated Nested Query (IN) Uncorrelated Nested Query (IN)

The inner query runs once. The outer query uses the result set. الاستعلام الداخلي يعمل مرة واحدة. الاستعلام الخارجي يستخدم مجموعة النتائج.

SELECT DISTINCT Pno FROM WORKS_ON WHERE Pno IN ( SELECT Pnumber FROM PROJECT WHERE Dnum = 5 );

Correlated Nested Query Correlated Nested Query (مترابط)

The inner query references a column from the outer query (E.Ssn). It runs once for every row of the outer table. الاستعلام الداخلي يشير إلى عمود من الاستعلام الخارجي (E.Ssn). يعمل مرة واحدة لكل صف في الجدول الخارجي.

SELECT E.Fname, E.Lname FROM EMPLOYEE AS E WHERE E.Salary > ( SELECT AVG(Salary) FROM EMPLOYEE WHERE Dno = E.Dno );

EXISTS Function دالة EXISTS

Checks if the inner query returns any rows. Returns TRUE or FALSE. تتحقق مما إذا كان الاستعلام الداخلي يُرجع أي صفوف. تُرجع TRUE أو FALSE.

SELECT Fname, Lname FROM EMPLOYEE AS E WHERE EXISTS ( SELECT * FROM DEPENDENT WHERE Essn = E.Ssn );

Outer Joins Outer Joins

Unlike Inner Join (which keeps only matching rows), Outer Joins keep rows even if they have no match (padding with NULLs). على عكس Inner Join (الذي يحتفظ فقط بالصفوف المتطابقة)، تحتفظ Outer Joins بالصفوف حتى لو لم يكن لها تطابق (مع التعبئة بـ NULLs).

LEFT OUTER JOIN LEFT OUTER JOIN Keep all rows from the Left table. الاحتفاظ بجميع الصفوف من الجدول الأيسر.
RIGHT OUTER JOIN RIGHT OUTER JOIN Keep all rows from the Right table. الاحتفاظ بجميع الصفوف من الجدول الأيمن.
FULL OUTER JOIN FULL OUTER JOIN Keep all rows from both tables. الاحتفاظ بجميع الصفوف من كلا الجدولين.
SELECT E.Lname, S.Lname FROM EMPLOYEE E LEFT OUTER JOIN EMPLOYEE S ON E.Super_ssn = S.Ssn;

Example: Lists all employees, even if they have no supervisor (S.Lname will be NULL). مثال: يسرد جميع الموظفين، حتى لو لم يكن لديهم مشرف (سيكون S.Lname بقيمة NULL).

Aggregate Functions & Grouping Aggregate Functions & Grouping

Aggregate Functions Aggregate Functions (دوال التجميع)

  • COUNT(*): Counts rows. يحسب الصفوف.
  • COUNT(Col): Counts non-null values. يحسب القيم غير الفارغة.
  • SUM, MAX, MIN, AVG: Math operations. عمليات رياضية.

GROUP BY & HAVING GROUP BY & HAVING

SELECT Dno, COUNT(*), AVG(Salary) FROM EMPLOYEE GROUP BY Dno HAVING AVG(Salary) > 30000;

HAVING filters groups AFTER grouping. HAVING يصفي المجموعات بعد التجميع.

Active Databases Active Databases (قواعد البيانات النشطة)

Triggers (E-C-A Model) Triggers (E-C-A Model)

A Trigger is a procedure automatically executed by the DBMS in response to specific events. Trigger هو إجراء يتم تنفيذه تلقائياً بواسطة الـ DBMS استجابة لأحداث معينة.

  • Event: INSERT, DELETE, UPDATE.
  • Condition: Optional check (WHEN).فحص اختياري (WHEN).
  • Action: SQL statements to execute.جمل SQL للتنفيذ.
CREATE TRIGGER INFORM_SUPERVISOR BEFORE INSERT OR UPDATE OF SALARY ON EMPLOYEE FOR EACH ROW WHEN (NEW.Salary > (SELECT Salary FROM EMPLOYEE WHERE Ssn = NEW.Super_ssn)) INFORM_SUPERVISOR(NEW.Super_ssn, NEW.Ssn);

The Exam Vault خزنة الاختبار

Professor's Secrets & Trap Avoidance أسرار البروفيسور وتجنب الفخاخ

TRAP: WHERE vs HAVING فخ: WHERE vs HAVING

WHERE filters rows before grouping.
HAVING filters groups after grouping.
You cannot put aggregate functions (e.g., `SUM(Salary)`) inside `WHERE`. They belong in `HAVING`.
WHERE يصفي الصفوف قبل التجميع.
HAVING يصفي المجموعات بعد التجميع.
لا يمكنك وضع دوال التجميع (مثل `SUM(Salary)`) داخل `WHERE`. مكانها في `HAVING`.

TRAP: NULL Comparisons فخ: مقارنات NULL

`WHERE Salary > 5000` will NOT return rows where Salary is NULL. NULL comparisons yield UNKNOWN, which is treated as FALSE in the WHERE clause. `WHERE Salary > 5000` لن يرجع الصفوف حيث الراتب NULL. مقارنات NULL تعطي UNKNOWN، والتي تعامل معاملة FALSE في جملة WHERE.

SECRET: Correlated Performance سر: Correlated Performance

Correlated nested queries are powerful but slow ($O(N^2)$ complexity) because the inner query executes once for every row of the outer table. Use JOINs instead for better performance. الاستعلامات المتداخلة المترابطة قوية ولكنها بطيئة (تعقيد $O(N^2)$) لأن الاستعلام الداخلي ينفذ مرة واحدة لكل صف من الجدول الخارجي. استخدم JOINs بدلاً منها لأداء أفضل.

KEY CONCEPT: COUNT(*) vs COUNT(Col) مفهوم أساسي: COUNT(*) vs COUNT(Col)

`COUNT(*)` counts all rows, including those with NULLs.
`COUNT(ColumnName)` counts only rows where that column is NOT NULL.
`COUNT(*)` يحسب جميع الصفوف، بما فيها التي تحتوي على NULLs.
`COUNT(ColumnName)` يحسب فقط الصفوف التي يكون العمود فيها ليس NULL.