DataBolt

All Lessons

Introduction to SQL
SQL Lesson 1: Your Sample Database
SQL Lesson 2: SELECT — Reading data
SQL Lesson 3: WHERE — Filtering rows
SQL Lesson 4: AND, OR, NOT
SQL Lesson 5: BETWEEN, IN, LIKE
SQL Lesson 6: NULL — The Mystery Value
SQL Lesson 7: ORDER BY
SQL Lesson 8: LIMIT & OFFSET
SQL Lesson 9: Aggregate Functions
SQL Lesson 10: GROUP BY
SQL Lesson 11: HAVING
SQL Lesson 12: INNER JOINs
SQL Lesson 13: LEFT JOINs
SQL Lesson 14: RIGHT JOINs
SQL Lesson 15: SELF JOINs
SQL Lesson 16: UNION JOINs
SQL Lesson 17: Joining Multiple Tables
SQL Lesson 18: Subqueries
SQL Lesson 19: CTEs (WITH)
SQL Lesson 20: CASE Statements
SQL Lesson 21: Window Functions
SQL Lesson 22: String Functions
SQL Lesson 23: Date & Time Functions
SQL Lesson 24: INSERT, UPDATE, DELETE
SQL Lesson 25: CREATE TABLE & DDL
SQL Lesson 26: Indexes & Performance
SQL Lesson 27: Transactions & ACID
SQL Lesson 28: SQL Execution Order
SQL Lesson 29: 50 Practice Problems

CHAPTER 19

Subqueries

Queries within queries — nesting for power.

IN THIS CHAPTER

  • Subquery in WHERE to filter on a computed value
  • Subquery with IN for list-based filtering
  • Subquery in FROM as a derived table
  • EXISTS — checking if a subquery returns any rows

🌟 Think of it this way: Subqueries are like asking two questions where the answer to the first feeds the second: 'What is the average salary?' → ₹70,125. 'Who earns more than ₹70,125?' Both steps happen in one SQL statement.

15.1 - Subquery in WHERE

Employees earning above the complany average

SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);

15.2 - Subquery in IN

Customers who ordered in January 2024

SELECT name FROM customers
WHERE customer_id IN (
  SELECT customer_id FROM orders
  WHERE order_date BETWEEN '2024-01-01' AND '2024-01-31'
);

15.3 - EXITS

EXISTS is faster than IN for large subqueries. It short-circuits as soon as one matching row is found:

SQL

SELECT c.name FROM customers c
WHERE EXISTS (
  SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id
);

💡 Engineering Insight: EXISTS vs IN performance: EXISTS stops scanning as soon as it finds the first match. IN collects every matching ID first. On tables with millions of rows, EXISTS can be 10-100x faster. Use EXISTS when you only care 'does a matching row exist?' not 'how many?'

Included Tables in Exercise

Table: Orders

order_idcustomer_idorder_datetotalstatus
112024-01-1579999completed
222024-01-203498completed
312024-02-1065000completed
432024-02-14499pending
522024-03-01248completed
652024-03-152999shipped
712024-04-05149completed

Table: Customers

customer_idnamecitycountry
1AnanyaHyderabadIndia
2RohanBangaloreIndia
3SamMumbaiIndia
4LisaLondonUK
5RaviDelhiIndia

Table: order_items

item_idorder_idproduct_idqtyunit_price
111179999
22312999
3221499
435165000
5421499
654299
756150
86312999

Table: products

product_idnamecategorypricestock
1iPhone 15Electronics7999950
2SQL BookBooks499200
3HeadphonesElectronics299975
4NotebookStationery99500
5LaptopElectronics6500020
6Pen SetStationery1490
7MouseElectronics59925

Exercise 👇

Exercise:

Tasks

1.👉Get the name and price of products whose price is greater than the average price of all products.
2.Find customers who have not placed any orders.
3.Find products that have been ordered with quantity greater than 1.
4.Find customers who have orders using EXISTS.
5.Find customers whose total order amount is greater than 50000.
6.Find products whose price is greater than the average price of all products.
Stuck? Read this task's