Introduction to SQL
SQL (Structured Query Language) is the standard language for communicating with relational databases. Whether you're working at a startup or a Fortune 500 company, SQL is the key to accessing and analyzing data stored in databases. It's one of the most in-demand skills for data analysts worldwide.
What is SQL?
SQL is a declarative language designed specifically for managing and querying data in relational databases. Unlike programming languages like Python, where you tell the computer HOW to do something step by step, SQL lets you declare WHAT you want, and the database figures out how to get it.
Understanding Relational Databases
A relational database stores data in tables (also called relations). Think of tables like Excel spreadsheets with rows and columns:
- Table: A collection of related data (e.g., customers, products, orders)
- Row (Record): A single entry in the table (e.g., one customer)
- Column (Field): An attribute or property (e.g., customer name, email)
-- This is what a table looks like conceptually
Table: employees
+----+------------+------------------+--------+--------+
| id | name | email | dept | salary |
+----+------------+------------------+--------+--------+
| 1 | Alice Chen | alice@company.com| Sales | 65000 |
| 2 | Bob Smith | bob@company.com | IT | 72000 |
| 3 | Carol Lee | carol@company.com| Sales | 68000 |
| 4 | David Wong | david@company.com| HR | 60000 |
+----+------------+------------------+--------+--------+
Popular Database Systems
SQL is used across many database management systems (DBMS). While the core SQL syntax is similar, each system has slight variations:
MySQL
Open-source, widely used for web applications. Powers WordPress, Facebook, and more.
PostgreSQL
Advanced open-source database with powerful features. Popular for analytics and data science.
Microsoft SQL Server
Enterprise-grade database from Microsoft. Common in corporate environments.
SQLite
Lightweight, file-based database. Great for learning, mobile apps, and small projects.
Why Learn SQL?
Career Essential
Required for data analyst, business analyst, and data scientist roles
Universal Skill
Works across industries - tech, finance, healthcare, retail, and more
Quick Results
Write a simple query and get answers from millions of rows instantly
Sample Database for This Lesson
Throughout this lesson, we'll use a sample store database with the following tables:
+----+------------------+----------+-------+-------+
| id | name | category | price | stock |
+----+------------------+----------+-------+-------+
| 1 | Laptop Pro 15 | Tech | 1299 | 45 |
| 2 | Wireless Mouse | Tech | 29 | 120 |
| 3 | Office Chair | Furniture| 249 | 30 |
| 4 | Standing Desk | Furniture| 599 | 15 |
| 5 | Headphones | Tech | 89 | 75 |
| 6 | Monitor 27" | Tech | 349 | 50 |
+----+------------------+----------+-------+-------+
Practice Questions: Understanding Databases
Question: Looking at the products table above, answer these questions:
- How many rows (records) are in the table?
- How many columns (fields) does the table have?
- What data type do you think the 'price' column stores?
- Which column would likely be the unique identifier?
Show Solution
Answers:
- 6 rows - Each product is one row (Laptop Pro 15, Wireless Mouse, etc.)
- 5 columns - id, name, category, price, stock
- Numeric (Decimal or Integer) - Price needs to store numbers like 1299 or 29.99
- id column - Each product has a unique ID number to identify it
Key Concepts:
- Primary Key: The 'id' column uniquely identifies each row
- Data Types: Columns have types (text, numbers, dates) to ensure data consistency
- Table Structure: Rows represent individual records, columns represent attributes
Task: Design a simple 'customers' table for an online store. Your table should track:
- Customer ID
- Full name
- Email address
- City
- Registration date
Draw or describe the table structure with appropriate column names and 3 sample rows of data.
Show Solution
Sample Table Design:
Table: customers
+----+----------------+---------------------+-------------+---------------+
| id | name | email | city | registered_at |
+----+----------------+---------------------+-------------+---------------+
| 1 | Sarah Johnson | sarah@email.com | New York | 2025-01-15 |
| 2 | Mike Chen | mike.chen@email.com | San Francisco| 2025-02-03 |
| 3 | Emily Rodriguez| emily.r@email.com | Chicago | 2025-02-10 |
+----+----------------+---------------------+-------------+---------------+
Design Considerations:
- id: Numeric primary key for unique identification
- name: Text field for customer's full name
- email: Text field (should be unique)
- city: Text field for location
- registered_at: Date field to track when they joined
Question: For each scenario below, explain how SQL could be used:
- An e-commerce company wants to find all orders from the last 30 days
- A manager needs to count how many employees work in each department
- A data analyst wants to calculate the average salary by job title
Show Solution
SQL Solutions:
- Recent Orders: Use WHERE clause to filter orders table by date >= 30 days ago
- Employee Count: Use GROUP BY to group employees by department and COUNT to get totals
- Average Salary: Use GROUP BY job title and AVG function to calculate average salaries
Why SQL is Perfect:
- SQL can filter millions of rows instantly (WHERE clause)
- Aggregate functions (COUNT, AVG, SUM) handle calculations automatically
- GROUP BY organizes data by categories effortlessly
- One query can answer complex business questions in seconds
SELECT Statement
The SELECT statement is the most fundamental and frequently used SQL command. It retrieves data from one or more tables. Think of it as asking the database a question: "Show me this information."
Basic SELECT Syntax
The simplest SELECT statement retrieves all columns from a table:
SELECT * FROM products;
SELECT- Keyword that starts the query*- Asterisk means "all columns"FROM- Specifies which table to queryproducts- The table name;- Semicolon marks the end (optional in many systems)
This query returns ALL rows and ALL columns from the products table.
Selecting Specific Columns
In practice, you rarely need all columns. Specify only the columns you need, separated by commas:
SELECT name, price FROM products;
This returns only the name and price columns for all products:
+------------------+-------+
| name | price |
+------------------+-------+
| Laptop Pro 15 | 1299 |
| Wireless Mouse | 29 |
| Office Chair | 249 |
| Standing Desk | 599 |
| Headphones | 89 |
| Monitor 27" | 349 |
+------------------+-------+
Calculated Columns
You can perform calculations in your SELECT statement:
SELECT name, price, stock, (price * stock) AS total_value
FROM products;
Result:
+------------------+-------+-------+-------------+
| name | price | stock | total_value |
+------------------+-------+-------+-------------+
| Laptop Pro 15 | 1299 | 45 | 58455 |
| Wireless Mouse | 29 | 120 | 3480 |
| Office Chair | 249 | 30 | 7470 |
| Standing Desk | 599 | 15 | 8985 |
| Headphones | 89 | 75 | 6675 |
| Monitor 27" | 349 | 50 | 17450 |
+------------------+-------+-------+-------------+
The AS keyword creates an alias (nickname) for the calculated column.
Instead of showing (price * stock) as the column name, it shows total_value.
DISTINCT Keyword
Use DISTINCT to remove duplicate values from results:
SELECT DISTINCT category FROM products;
Result:
+-----------+
| category |
+-----------+
| Tech |
| Furniture |
+-----------+
Without DISTINCT, you'd see "Tech" repeated 4 times (for each tech product).
String Operations
SQL provides functions to manipulate text:
SELECT
UPPER(name) AS name_uppercase,
LOWER(category) AS category_lowercase,
CONCAT(name, ' - ', category) AS product_info
FROM products
LIMIT 3;
Result:
+------------------+--------------------+---------------------------+
| name_uppercase | category_lowercase | product_info |
+------------------+--------------------+---------------------------+
| LAPTOP PRO 15 | tech | Laptop Pro 15 - Tech |
| WIRELESS MOUSE | tech | Wireless Mouse - Tech |
| OFFICE CHAIR | furniture | Office Chair - Furniture |
+------------------+--------------------+---------------------------+
Practice Questions: SELECT Statement
Task: Write a query to select only the name and stock columns from the products table.
Show Solution
Solution:
SELECT name, stock FROM products;
Why This Works:
- SELECT specifies which columns to retrieve
- Column names are separated by commas
- FROM specifies the source table
- This returns all rows but only the name and stock columns
Task: Write a query that shows each product's name and its price with a 20% discount. Use the alias 'discount_price' for the calculated column.
Show Solution
Solution:
SELECT name, (price * 0.8) AS discount_price
FROM products;
Explanation:
- Multiplying by 0.8 gives 80% of original price (20% off)
- Alternative:
price - (price * 0.2)also works - AS keyword creates a readable column name
Sample Result:
+------------------+----------------+
| name | discount_price |
+------------------+----------------+
| Laptop Pro 15 | 1039.20 |
| Wireless Mouse | 23.20 |
| Office Chair | 199.20 |
+------------------+----------------+
Challenge: Create a query that shows:
- Product name in UPPERCASE
- Original price
- Price with 15% tax (alias: price_with_tax)
- Total inventory value with tax (alias: total_value_with_tax)
Show Solution
Solution:
SELECT
UPPER(name) AS name,
price,
(price * 1.15) AS price_with_tax,
(price * 1.15 * stock) AS total_value_with_tax
FROM products;
Breaking It Down:
UPPER(name)- Converts name to uppercaseprice * 1.15- Adds 15% tax (multiply by 1.15)price * 1.15 * stock- Calculates total value with tax- Each calculation gets a descriptive alias
Key Concepts:
- You can combine multiple functions and calculations in one SELECT
- Order of operations matters: multiplication before addition
- Use parentheses for complex calculations
- Descriptive aliases make results easier to understand
WHERE Clause
The WHERE clause filters rows based on specified conditions. Instead of retrieving all rows, you get only the rows that meet your criteria. This is essential for working with large databases.
Basic WHERE Syntax
SELECT name, price, category
FROM products
WHERE category = 'Tech';
Result - only Tech products:
+------------------+-------+----------+
| name | price | category |
+------------------+-------+----------+
| Laptop Pro 15 | 1299 | Tech |
| Wireless Mouse | 29 | Tech |
| Headphones | 89 | Tech |
| Monitor 27" | 349 | Tech |
+------------------+-------+----------+
'Tech', 'tech', and 'TECH' are usually treated the same.
Comparison Operators
SQL supports several comparison operators:
Numeric Comparisons
| Operator | Meaning | Example |
|---|---|---|
= |
Equal to | price = 100 |
!= or <> |
Not equal | stock != 0 |
> |
Greater than | price > 500 |
< |
Less than | stock < 50 |
>= |
Greater or equal | price >= 100 |
<= |
Less or equal | stock <= 30 |
Text & Special Operators
| Operator | Meaning | Example |
|---|---|---|
BETWEEN |
Within range | price BETWEEN 100 AND 500 |
IN |
Match any value in list | category IN ('Tech', 'Office') |
LIKE |
Pattern matching | name LIKE '%Mouse%' |
IS NULL |
Value is NULL | discount IS NULL |
IS NOT NULL |
Value is not NULL | email IS NOT NULL |
LIKE Operator & Wildcards
The LIKE operator performs pattern matching using wildcards:
%- Matches zero or more characters_- Matches exactly one character
SELECT name FROM products
WHERE name LIKE 'Laptop%';
Finds: "Laptop Pro 15", "Laptop Air 13"
SELECT name FROM products
WHERE name LIKE '%Mouse%';
Finds: "Wireless Mouse", "Gaming Mouse"
SELECT name FROM products
WHERE name LIKE '%Desk';
Finds: "Standing Desk", "Adjustable Desk"
SELECT name FROM products
WHERE name LIKE '_o%';
Finds: "Monitor 27"" (second letter is 'o')
Logical Operators (AND, OR, NOT)
Combine multiple conditions using logical operators:
SELECT name, price, stock
FROM products
WHERE category = 'Tech' AND price < 100;
Result - Tech products under $100:
+------------------+-------+-------+
| name | price | stock |
+------------------+-------+-------+
| Wireless Mouse | 29 | 120 |
| Headphones | 89 | 75 |
+------------------+-------+-------+
SELECT name, price, category
FROM products
WHERE price > 500 OR stock < 20;
Result - Products either expensive OR low stock:
+------------------+-------+-----------+
| name | price | category |
+------------------+-------+-----------+
| Laptop Pro 15 | 1299 | Tech |
| Standing Desk | 599 | Furniture |
+------------------+-------+-----------+
SELECT name, category
FROM products
WHERE NOT category = 'Tech';
Result - All non-Tech products:
+------------------+-----------+
| name | category |
+------------------+-----------+
| Office Chair | Furniture |
| Standing Desk | Furniture |
+------------------+-----------+
Combining Multiple Conditions
Use parentheses to group conditions and control evaluation order:
SELECT name, price, stock, category
FROM products
WHERE (category = 'Tech' AND price < 100)
OR (category = 'Furniture' AND stock > 25);
This finds:
- Tech products under $100, OR
- Furniture with stock over 25
- Parentheses first
- NOT
- AND
- OR
Always use parentheses to make your intent clear!
Practice Questions: WHERE Clause
Task: Write a query to find all products with a price greater than or equal to $300.
Show Solution
Solution:
SELECT name, price FROM products
WHERE price >= 300;
Expected Result:
+------------------+-------+
| name | price |
+------------------+-------+
| Laptop Pro 15 | 1299 |
| Standing Desk | 599 |
| Monitor 27" | 349 |
+------------------+-------+
Note:
>= means "greater than or equal to", so $300 would be included if it existed.
Task: Find all products whose name contains the word "Pro" anywhere in it.
Show Solution
Solution:
SELECT name, price FROM products
WHERE name LIKE '%Pro%';
Explanation:
%Pro%matches "Pro" anywhere in the name- First
%matches any characters before "Pro" - Second
%matches any characters after "Pro" - Would find: "Laptop Pro 15", "MacBook Pro", "Pro Mouse"
Expected Result:
+------------------+-------+
| name | price |
+------------------+-------+
| Laptop Pro 15 | 1299 |
+------------------+-------+
Challenge: Find products that meet ALL these criteria:
- Category is either 'Tech' or 'Office'
- Price is between $50 and $500
- Stock is greater than 40
Show Solution
Solution:
SELECT name, price, stock, category
FROM products
WHERE category IN ('Tech', 'Office')
AND price BETWEEN 50 AND 500
AND stock > 40;
Alternative Approach:
SELECT name, price, stock, category
FROM products
WHERE (category = 'Tech' OR category = 'Office')
AND (price >= 50 AND price <= 500)
AND stock > 40;
Key Concepts:
INoperator is cleaner than multiple ORsBETWEENis inclusive (includes 50 and 500)- All three conditions connected by AND must be true
- Proper indentation makes complex queries readable
Expected Result:
+------------------+-------+-------+----------+
| name | price | stock | category |
+------------------+-------+-------+----------+
| Monitor 27" | 349 | 50 | Tech |
| Headphones | 89 | 75 | Tech |
+------------------+-------+-------+----------+
Sorting with ORDER BY
The ORDER BY clause sorts query results by one or more columns. By default, database rows have no guaranteed order, so ORDER BY is essential when you need sorted results.
Basic Sorting
SELECT name, price FROM products
ORDER BY price;
Result - cheapest to most expensive:
+------------------+-------+
| name | price |
+------------------+-------+
| Wireless Mouse | 29 |
| Headphones | 89 |
| Office Chair | 249 |
| Monitor 27" | 349 |
| Standing Desk | 599 |
| Laptop Pro 15 | 1299 |
+------------------+-------+
When you use ORDER BY without specifying, SQL sorts in ascending order (ASC) by default. For numbers: smallest to largest. For text: A to Z.
Descending Order
Use DESC keyword to sort in descending order (largest to smallest, Z to A):
SELECT name, price FROM products
ORDER BY price DESC;
Result - most expensive to cheapest:
+------------------+-------+
| name | price |
+------------------+-------+
| Laptop Pro 15 | 1299 |
| Standing Desk | 599 |
| Monitor 27" | 349 |
| Office Chair | 249 |
| Headphones | 89 |
| Wireless Mouse | 29 |
+------------------+-------+
Sorting by Multiple Columns
You can sort by multiple columns. SQL sorts by the first column, then uses subsequent columns as tiebreakers:
SELECT name, category, price FROM products
ORDER BY category, price DESC;
Result - grouped by category, then by price within each category:
+------------------+-----------+-------+
| name | category | price |
+------------------+-----------+-------+
| Standing Desk | Furniture | 599 |
| Office Chair | Furniture | 249 |
| Laptop Pro 15 | Tech | 1299 |
| Monitor 27" | Tech | 349 |
| Headphones | Tech | 89 |
| Wireless Mouse | Tech | 29 |
+------------------+-----------+-------+
ORDER BY category ASC, price DESC
Sorting Text
When sorting text columns, SQL uses alphabetical order:
SELECT name, price FROM products
ORDER BY name;
Result - alphabetical order (A to Z):
+------------------+-------+
| name | price |
+------------------+-------+
| Headphones | 89 |
| Laptop Pro 15 | 1299 |
| Monitor 27" | 349 |
| Office Chair | 249 |
| Standing Desk | 599 |
| Wireless Mouse | 29 |
+------------------+-------+
Sorting by Calculated Columns
You can order by calculated values:
SELECT name, price, stock, (price * stock) AS total_value
FROM products
ORDER BY (price * stock) DESC;
Result - highest total value first:
+------------------+-------+-------+-------------+
| name | price | stock | total_value |
+------------------+-------+-------+-------------+
| Laptop Pro 15 | 1299 | 45 | 58455 |
| Monitor 27" | 349 | 50 | 17450 |
| Standing Desk | 599 | 15 | 8985 |
| Office Chair | 249 | 30 | 7470 |
| Headphones | 89 | 75 | 6675 |
| Wireless Mouse | 29 | 120 | 3480 |
+------------------+-------+-------+-------------+
Practice Questions: ORDER BY
Task: Write a query to list all products sorted by stock quantity from highest to lowest.
Show Solution
Solution:
SELECT name, stock FROM products
ORDER BY stock DESC;
Explanation:
DESCsorts from highest to lowest- Shows which products have the most inventory
- Useful for inventory management
Expected Result:
+------------------+-------+
| name | stock |
+------------------+-------+
| Wireless Mouse | 120 |
| Headphones | 75 |
| Monitor 27" | 50 |
| Laptop Pro 15 | 45 |
| Office Chair | 30 |
| Standing Desk | 15 |
+------------------+-------+
Task: Find all Tech products and sort them by stock (lowest first), then by price (highest first) for products with the same stock level.
Show Solution
Solution:
SELECT name, price, stock FROM products
WHERE category = 'Tech'
ORDER BY stock ASC, price DESC;
Explanation:
- First filters to show only Tech products
- Sorts by stock ascending (lowest stock first - these need reordering)
- For items with same stock, shows expensive ones first
- Each column can have its own sort direction
Expected Result:
+------------------+-------+-------+
| name | price | stock |
+------------------+-------+-------+
| Laptop Pro 15 | 1299 | 45 |
| Monitor 27" | 349 | 50 |
| Headphones | 89 | 75 |
| Wireless Mouse | 29 | 120 |
+------------------+-------+-------+
Challenge: Create a report showing products with price over $100, displaying name, price, and stock. Sort by category (alphabetically), then by the calculated profit margin percentage (price - 20% cost) in descending order.
Assume cost is 60% of price (so profit margin = price * 0.4 / price = 40%)
Show Solution
Solution:
SELECT
name,
price,
stock,
category,
(price * 0.4) AS profit_margin
FROM products
WHERE price > 100
ORDER BY category ASC, profit_margin DESC;
Breaking It Down:
WHERE price > 100filters to expensive products only(price * 0.4)calculates 40% profit marginAS profit_marginnames the calculated column- First sorts by category alphabetically
- Within each category, highest profit margin first
Key Concepts:
- Can combine WHERE with ORDER BY
- Can sort by calculated columns
- Multi-column sorts process left to right
- Useful for business analytics and reporting
Limiting Results
The LIMIT clause restricts the number of rows returned by a query. This is crucial when working with large datasets where you only need to see a sample or the "top N" results.
Basic LIMIT Usage
SELECT name, price FROM products
LIMIT 3;
Result - only 3 rows:
+------------------+-------+
| name | price |
+------------------+-------+
| Laptop Pro 15 | 1299 |
| Wireless Mouse | 29 |
| Office Chair | 249 |
+------------------+-------+
LIMIT with ORDER BY
Combine LIMIT with ORDER BY to get "top N" results:
SELECT name, price FROM products
ORDER BY price DESC
LIMIT 3;
Result:
+------------------+-------+
| name | price |
+------------------+-------+
| Laptop Pro 15 | 1299 |
| Standing Desk | 599 |
| Monitor 27" | 349 |
+------------------+-------+
SELECT name, price FROM products
ORDER BY price ASC
LIMIT 3;
Result:
+------------------+-------+
| name | price |
+------------------+-------+
| Wireless Mouse | 29 |
| Headphones | 89 |
| Office Chair | 249 |
+------------------+-------+
OFFSET for Pagination
Use OFFSET to skip rows, useful for pagination (e.g., showing results page by page):
LIMIT number OFFSET skip_count
Or shorter: LIMIT skip_count, number (MySQL style)
SELECT name, price FROM products
ORDER BY price
LIMIT 2 OFFSET 2;
Result - products #3 and #4 by price:
+------------------+-------+
| name | price |
+------------------+-------+
| Office Chair | 249 |
| Monitor 27" | 349 |
+------------------+-------+
Pagination Example
Here's how to implement pagination (showing 2 items per page):
SELECT name, price FROM products
ORDER BY name
LIMIT 2 OFFSET 0;
SELECT name, price FROM products
ORDER BY name
LIMIT 2 OFFSET 2;
SELECT name, price FROM products
ORDER BY name
LIMIT 2 OFFSET 4;
-- OFFSET = (page_number - 1) * items_per_page
-- For page 5 with 10 items per page:
-- OFFSET = (5 - 1) * 10 = 40
Database Differences
MySQL / PostgreSQL / SQLite
SELECT * FROM products
LIMIT 5;
-- With offset
SELECT * FROM products
LIMIT 5 OFFSET 10;
SQL Server
SELECT TOP 5 * FROM products;
-- With offset (requires ORDER BY)
SELECT * FROM products
ORDER BY id
OFFSET 10 ROWS
FETCH NEXT 5 ROWS ONLY;
Practice Questions: LIMIT
Task: Write a query to show the 5 products with the highest stock quantities.
Show Solution
Solution:
SELECT name, stock FROM products
ORDER BY stock DESC
LIMIT 5;
Explanation:
ORDER BY stock DESCputs highest stock firstLIMIT 5takes only the first 5 results- Useful for finding best-stocked items
Task: You're displaying products in a catalog with 3 items per page. Write a query to get the products for page 2, sorted alphabetically by name.
Show Solution
Solution:
SELECT name, price FROM products
ORDER BY name
LIMIT 3 OFFSET 3;
Explanation:
- Page 1 would be:
LIMIT 3 OFFSET 0(items 1-3) - Page 2 is:
LIMIT 3 OFFSET 3(items 4-6) - Formula: OFFSET = (page_number - 1) × items_per_page
- So: (2 - 1) × 3 = 3
Expected Result (Page 2):
+------------------+-------+
| name | price |
+------------------+-------+
| Office Chair | 249 |
| Standing Desk | 599 |
| Wireless Mouse | 29 |
+------------------+-------+
Challenge: Create a query that shows:
- Top 3 Tech products by total inventory value (price × stock)
- Display: name, price, stock, and calculated total_value
- Only include products with stock > 40
Show Solution
Solution:
SELECT
name,
price,
stock,
(price * stock) AS total_value
FROM products
WHERE category = 'Tech' AND stock > 40
ORDER BY (price * stock) DESC
LIMIT 3;
Query Flow:
- WHERE: Filters to Tech products with stock > 40
- SELECT: Calculates total_value for each row
- ORDER BY: Sorts by total_value (highest first)
- LIMIT: Takes only top 3 results
Key Concepts:
- SQL processes: WHERE → SELECT → ORDER BY → LIMIT
- Can use calculated columns in ORDER BY
- Combines filtering, calculation, sorting, and limiting
- This type of query is common in business analytics
Expected Result:
+------------------+-------+-------+-------------+
| name | price | stock | total_value |
+------------------+-------+-------+-------------+
| Laptop Pro 15 | 1299 | 45 | 58455 |
| Monitor 27" | 349 | 50 | 17450 |
| Headphones | 89 | 75 | 6675 |
+------------------+-------+-------+-------------+
Key Takeaways
SQL is Universal
SQL is the standard language for relational databases used by companies worldwide
SELECT Retrieves Data
The SELECT statement is your primary tool for querying and retrieving data from tables
WHERE Filters Rows
Use WHERE clause to filter data based on conditions and get exactly the rows you need
ORDER BY Sorts Results
Control the order of your results with ORDER BY for ascending or descending sorts
LIMIT Controls Size
Use LIMIT to control how many rows are returned in your query results
Practice is Essential
SQL mastery comes from writing queries - practice with real databases regularly
Knowledge Check
Test your understanding of SQL basics: