Database Management SystemUnit 413 min read
SQL and Query Processing: Syntax, Joins, Subqueries, and Optimization
Unit 4 of Database Management System: This note explains SQL’s core syntax, query processing (SELECT, WHERE, GROUP BY, HAVING), joins (INNER, LEFT, RIGHT, FULL), subqueries, and optimization techniques, with real-world examples from eSewa, Daraz, and NTC.
TAKEAWAYS:
- SQL is a declarative language for querying relational databases, not procedural (no line-by-line execution).
- Joins combine tables via keys (e.g.,
INNER JOINmerges matching rows;LEFT JOINkeeps all left-table rows). - Subqueries nest queries inside others (e.g.,
WHERE salary > (SELECT AVG(salary) FROM employees)). - Query optimization relies on indexes, execution plans, and cost-based estimators (e.g., MySQL’s
EXPLAIN). - Embedded SQL integrates SQL into application code (e.g., Java’s JDBC, Python’s
sqlite3). - Real-world use: eSewa’s transaction logs use SQL joins to link users, payments, and merchants; Daraz’s order queues rely on
GROUP BYto track inventory by product.
1. Introduction to SQL
SQL (Structured Query Language) is the standard language for interacting with relational databases. It supports:
- Data Definition Language (DDL):
CREATE,ALTER,DROP(e.g.,CREATE TABLE employees (EmpID INT PRIMARY KEY, Name VARCHAR(50))). - Data Manipulation Language (DML):
INSERT,UPDATE,DELETE,SELECT. - Data Control Language (DCL):
GRANT,REVOKE(permissions).
Why SQL?
Before databases, file systems stored data redundantly (e.g., employee records duplicated in HR and Payroll files). SQL eliminates this by centralizing data in tables with keys (primary/foreign) and enforcing integrity (e.g., no duplicate EmpID).
1.1 SQL vs. File Processing
| Aspect | File Processing | SQL Database |
|---|---|---|
| Data Redundancy | High (same data copied across files) | Low (data stored once in tables) |
| Data Integrity | Manual (risk of inconsistency) | Enforced (constraints like NOT NULL) |
| Query Complexity | Procedural (write loops for filtering) | Declarative (write WHERE clauses) |
| Concurrency Control | None (race conditions likely) | Transactions (BEGIN, COMMIT, ROLLBACK) |
Example: A company’s HR file might store employee salaries in both the employees and payroll files. If the salary changes in one file but not the other, inconsistency arises. SQL avoids this by linking tables via foreign keys (e.g., DeptID in employees references DeptID in departments).
2. Core SQL Queries
SQL queries follow the SELECT-FROM-WHERE structure:
SELECT column1, column2
FROM table1
WHERE condition
GROUP BY column3
HAVING group_condition
ORDER BY column4;
2.1 SELECT and Projections
Projection: Select specific columns.
-- List all employees in the 'IT' department
SELECT FirstName, LastName, Salary
FROM employees
WHERE DeptID = (SELECT DeptID FROM departments WHERE DeptName = 'IT');
Visualization:
graph TD A["employees"] -->|"DeptID = (SELECT DeptID FROM departments WHERE DeptName = 'IT')"| B["Subquery Result: DeptID=10"] B -->|"DeptID=10"| C["employees (filtered)"] C -->|"Result"| D["Final Result: IT employees"]
2.2 WHERE and Filtering
Filters rows based on conditions:
-- Employees earning > $50,000
SELECT *
FROM employees
WHERE Salary > 50000;
Real-world tie: NTC’s call records use WHERE to filter active users by location:
SELECT user_id, call_duration
FROM call_logs
WHERE location = 'Kathmandu' AND call_duration > 300;
2.3 GROUP BY and Aggregation
Groups rows and computes aggregates (COUNT, SUM, AVG):
-- Average salary by department
SELECT DeptName, AVG(Salary)
FROM employees e
JOIN departments d ON e.DeptID = d.DeptID
GROUP BY DeptName;
Visualization:
2.4 HAVING vs. WHERE
WHEREfilters before grouping.HAVINGfilters after grouping.
-- Departments with >3 employees
SELECT DeptName, COUNT(*)
FROM employees e
JOIN departments d ON e.DeptID = d.DeptID
GROUP BY DeptName
HAVING COUNT(*) > 3;
3. Joins: Combining Tables
Joins link tables via keys. Types:
| Join Type | Description | SQL Syntax | Example Use Case |
|---|---|---|---|
| INNER JOIN | Returns matching rows only. | FROM A INNER JOIN B ON A.key = B.key |
eSewa’s user-payment links. |
| LEFT JOIN | All left-table rows + matching right rows. | FROM A LEFT JOIN B ON ... |
Daraz’s orders (all orders + products). |
| RIGHT JOIN | All right-table rows + matching left rows. | FROM A RIGHT JOIN B ON ... |
Rare; often replaced by LEFT JOIN. |
| FULL JOIN | All rows from both tables. | FROM A FULL JOIN B ON ... |
Merging customer and supplier data. |
| CROSS JOIN | Cartesian product (all combinations). | FROM A CROSS JOIN B |
Testing all product-price pairs. |
Worked Example: Link employees and departments to find IT salaries.
-- INNER JOIN: Only IT employees
SELECT e.FirstName, d.DeptName, e.Salary
FROM employees e
INNER JOIN departments d ON e.DeptID = d.DeptID
WHERE d.DeptName = 'IT';
-- LEFT JOIN: All employees (even non-IT)
SELECT e.FirstName, d.DeptName, e.Salary
FROM employees e
LEFT JOIN departments d ON e.DeptID = d.DeptID;
Visualization:
graph TD A["employees"] -->|"DeptID"| B["departments"] B -->|"DeptName"| C["INNER JOIN Result"] A -->|"All rows"| D["LEFT JOIN Result (includes NULLs)"] C -->|"e.DeptID=d.DeptID"| C D -->|"e.DeptID=d.DeptID or NULL"| D
4. Subqueries and Nested Queries
Subqueries run inside other queries. Types:
- Scalar Subquery: Returns a single value.
-- Employees earning > avg salary SELECT FirstName, Salary FROM employees WHERE Salary > (SELECT AVG(Salary) FROM employees); - Correlated Subquery: Depends on outer query.
-- Employees earning more than their manager SELECT e.FirstName, e.Salary FROM employees e WHERE e.Salary > (SELECT m.Salary FROM employees m WHERE m.EmpID = e.ManagerID); - IN Subquery: Checks membership.
-- Employees in IT or HR SELECT * FROM employees WHERE DeptID IN (SELECT DeptID FROM departments WHERE DeptName IN ('IT', 'HR'));
Real-world tie: Pathao’s driver availability uses subqueries to check:
-- Drivers available in Kathmandu with >4.5 rating
SELECT driver_id, rating
FROM drivers
WHERE location = 'Kathmandu'
AND rating > (SELECT AVG(rating) FROM drivers WHERE location = 'Kathmandu');
5. Advanced Querying: UNION, INTERSECT, EXCEPT
| Operator | Description | Example |
|---|---|---|
| UNION | Combines results (removes duplicates). | SELECT ... FROM A UNION SELECT ... FROM B |
| INTERSECT | Returns common rows. | SELECT ... FROM A INTERSECT SELECT ... FROM B |
| EXCEPT | Returns rows in A but not B. | SELECT ... FROM A EXCEPT SELECT ... FROM B |
Example: Find employees in both IT and HR (using INTERSECT).
-- Employees in IT AND HR (unlikely, but possible)
SELECT EmpID
FROM employees
WHERE DeptID IN (SELECT DeptID FROM departments WHERE DeptName = 'IT')
INTERSECT
SELECT EmpID
FROM employees
WHERE DeptID IN (SELECT DeptID FROM departments WHERE DeptName = 'HR');
6. Query Optimization
Optimization improves performance by:
- Indexing: Speeds up
WHEREclauses (e.g., index onEmpID).CREATE INDEX idx_empid ON employees(EmpID); - Execution Plans: Databases generate plans (e.g., MySQL’s
EXPLAIN).
Output:EXPLAIN SELECT * FROM employees WHERE DeptID = 10;+----+-------------+----------+------------+-------+---------------+---------+----------+------+------+----------+----------------+ | id | select_type | table | type | key | key_len | ref | rows | Extra | ... | | +----+-------------+----------+------------+-------+---------------+---------+----------+------+------+----------+----------------+ | 1 | SIMPLE | employees| const | PRIMARY| 4 | const | 1 | NULL | ... | | +----+-------------+----------+------------+-------+---------------+---------+----------+------+------+----------+----------------+type: constmeans the query uses the index directly (fast).rows: 1suggests only one row is scanned.
- Cost-Based Optimizer: Estimates the "cost" (I/O, CPU) of each plan and picks the cheapest.
Real-world tie: NEPSE’s stock queries use indexes on symbol and timestamp to avoid full-table scans:
-- Optimized: Index on (symbol, timestamp)
SELECT symbol, price
FROM stocks
WHERE symbol = 'NEPSE' AND timestamp > '2023-01-01';
7. Embedded SQL
Embedded SQL integrates SQL into application code (e.g., Java, Python). Example in Python with SQLite:
import sqlite3
conn = sqlite3.connect('company.db')
cursor = conn.cursor()
# Embedded SQL (DML)
cursor.execute("SELECT * FROM employees WHERE Salary > ?", (50000,))
results = cursor.fetchall()
for row in results:
print(row)
conn.close()
Advantages:
- Reuses database logic in apps (e.g., eSewa’s transaction validation).
- Reduces redundant code (e.g., Daraz’s inventory checks).
Disadvantages:
- Security risk if inputs aren’t sanitized (SQL injection).
- Tight coupling between app and database.
8. Transaction Management in Queries
Transactions ensure ACID properties (Atomicity, Consistency, Isolation, Durability). Example:
-- Transfer $1000 from Emp1 to Emp2
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 1000 WHERE emp_id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE emp_id = 2;
COMMIT;
If the second update fails, the transaction rolls back to avoid inconsistency.
Real-world tie: Khalti’s payment processing uses transactions:
-- Atomic transfer: User → Merchant
BEGIN;
UPDATE user_accounts SET balance = balance - 100 WHERE user_id = 123;
UPDATE merchant_accounts SET balance = balance + 100 WHERE merchant_id = 456;
COMMIT;
In the real world
eSewa’s Transaction Logs
- Idea: Uses INNER JOINs to link user transactions, merchants, and timestamps.
- Query:
SELECT user_id, merchant_id, amount FROM transactions JOIN users ON transactions.user_id = users.id WHERE status = 'completed'; - Why it matters: Ensures no double-charging and tracks fraud.
Daraz’s Order Queues
- Idea: GROUP BY and HAVING aggregate orders by product to manage inventory.
- Query:
SELECT product_id, COUNT(*) FROM orders GROUP BY product_id HAVING COUNT(*) > 100; - Why it matters: Triggers restock alerts for high-demand items.
NTC’s Call Routing
- Idea: Subqueries filter active users by location and signal strength.
- Query:
SELECT user_id FROM call_logs WHERE location = 'Pokhara' AND signal > 80; - Why it matters: Routes calls to the nearest tower for faster connectivity.
Exam Tip
- Focus on joins: 30% of exam questions test
INNER,LEFT,RIGHTjoins. Practice linking 2–3 tables. - Subqueries are high-yield: Expect 1–2 questions on scalar/correlated subqueries. Memorize the
INsyntax. - Optimization is practical: Know
EXPLAIN, indexes, andGROUP BYvs.HAVING. Draw execution plans for full marks. - Embedded SQL: Show how to embed a
SELECTin Python/Java. Avoid raw SQL injection examples. - Transactions: Always pair
BEGIN/COMMITwithROLLBACKin failure cases. Use a real-world example (e.g., bank transfer).
Common Pitfalls:
- Forgetting
ONin joins (e.g.,FROM A JOIN Bis invalid; must specifyON A.key = B.key). - Confusing
WHERE(row-level) andHAVING(group-level). - Overlooking
DISTINCTinUNION(it removes duplicates by default).
| Component | Description |
|---|---|
| Optimizer | Chooses the fastest query plan. |
| Index Scan | Uses indexes for fast lookups. |
| Nested Loop | Joins tables row-by-row (slow for large data). |
| Hash Join | Builds a hash table for O(1) lookups. |
| Component | Role in SQL Processing |
|---|---|
| Router | Directs client requests to the DB server. |
| Server Rack | Hosts the database engine (e.g., MySQL). |
| Storage (SSD/HDD) | Stores tables and indexes. |
Mermaid Diagram: SQL Query Execution Flow
sequenceDiagram
participant Client as User/App
participant DB as Database Engine
participant Storage as Disk/Index
Client->>DB: EXECUTE SELECT * FROM employees WHERE Salary > 50000
DB->>Storage: Check index on Salary (B-tree)
Storage-->>DB: Returns matching EmpIDs (100, 200, 300)
DB->>Storage: Fetch full rows for EmpIDs 100, 200, 300
Storage-->>DB: Returns employee records
DB-->>Client: Returns 3 rowsBased on the TU BITM syllabus for Database Management System (IT220), unit 4.
Discussion
Loading…