COURSE ยท 8 LESSONS ยท 100% FREE
๐Ÿ—ƒ๏ธ

SQL (Database Queries)

The language of databases. Query, insert, update, and manage data in MySQL, PostgreSQL, SQLite.

0Lessons
0Code Examples
ZeroPrerequisites
0%
You've completed 0 of 8 lessons
J/โ†“ Next
K/โ†‘ Prev
Esc Collapse
/ Search
Foundations
01

SELECT & Filtering

SELECT columns FROM table WHERE conditions. The bread and butter of SQL.

๐Ÿง  Note for the confused:
SELECT is SQL's way of saying 'show me what you got.' SELECT * FROM users = 'give me EVERYTHING from the users table.' It's like asking someone to empty their entire wallet on the table. Aggressive, but effective.
-- Basic select
SELECT * FROM users;
SELECT name, email FROM users;

-- Filtering
SELECT * FROM users WHERE age > 18;
SELECT * FROM users WHERE name LIKE '%Mayank%';
SELECT * FROM users WHERE age BETWEEN 10 AND 20;
SELECT * FROM users WHERE name IN ('Alice', 'Bob');
SELECT * FROM users WHERE email IS NOT NULL;

-- Ordering
SELECT * FROM users ORDER BY age DESC;
SELECT * FROM users ORDER BY name ASC;

-- Limit
SELECT * FROM users LIMIT 10;
SELECT * FROM users LIMIT 10 OFFSET 20;  -- pagination
02

INSERT, UPDATE, DELETE

Modify data. INSERT adds rows, UPDATE changes them, DELETE removes them.

๐Ÿง  Note for the confused:
INSERT is adding new rows to a table. Like putting a new photo in an album. UPDATE is changing existing data. Like editing someone's yearbook photo to give them a mustache. DELETE is... well, you can guess.
-- Insert
INSERT INTO users (name, email, age) VALUES ('Mayank', 'mayank@test.com', 15);
INSERT INTO users (name, email, age) VALUES
  ('Alice', 'alice@test.com', 20),
  ('Bob', 'bob@test.com', 12);

-- Update
UPDATE users SET age = 16 WHERE name = 'Mayank';
UPDATE users SET email = 'new@test.com', age = 21 WHERE id = 1;

-- Delete
DELETE FROM users WHERE id = 5;
DELETE FROM users WHERE age < 10;
-- TRUNCATE TABLE users;  -- fast delete all
03

JOINs

Combine rows from multiple tables. INNER, LEFT, RIGHT, FULL, CROSS.

๐Ÿง  Note for the confused:
JOINs are SQL's way of connecting tables. INNER JOIN gives you only the matches. LEFT JOIN keeps everything from the left table even if the right table ghosts you. It's relationship advice for databases.
-- INNER JOIN (only matching rows)
SELECT users.name, orders.product
FROM users
INNER JOIN orders ON users.id = orders.user_id;

-- LEFT JOIN (all from left, matching from right)
SELECT users.name, COALESCE(orders.product, 'None')
FROM users
LEFT JOIN orders ON users.id = orders.user_id;

-- RIGHT JOIN
SELECT users.name, orders.product
FROM users
RIGHT JOIN orders ON users.id = orders.user_id;

-- CROSS JOIN (every combination)
SELECT users.name, products.name
FROM users
CROSS JOIN products;

-- Self join
SELECT a.name AS employee, b.name AS manager
FROM employees a
INNER JOIN employees b ON a.manager_id = b.id;
04

GROUP BY & Aggregates

count, sum, avg, min, max. GROUP BY clusters rows. HAVING filters groups.

๐Ÿง  Note for the confused:
GROUP BY is SQL's way of organizing things into piles. 'Give me all users grouped by country.' It's like sorting your laundry but with data instead of socks.
-- Aggregate functions
SELECT COUNT(*) FROM users;
SELECT AVG(age) FROM users;
SELECT MAX(age), MIN(age) FROM users;
SELECT SUM(salary) FROM employees;

-- GROUP BY
SELECT grade, COUNT(*) AS count
FROM students
GROUP BY grade;

SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
ORDER BY avg_salary DESC;

-- HAVING (filter groups)
SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;

-- Multiple groups
SELECT grade, gender, COUNT(*)
FROM students
GROUP BY grade, gender
ORDER BY grade;
Advanced
05

Subqueries & CTEs

Queries inside queries. WITH for common table expressions. Window functions.

๐Ÿง  Note for the confused:
HAVING is like WHERE but for groups. WHERE filters individual rows. HAVING filters groups. It's the difference between 'don't invite Bob' and 'don't invite any group Bob is in.' Subtle but important.
-- Subquery
SELECT * FROM users
WHERE id IN (SELECT user_id FROM orders WHERE amount > 100);

-- CTE (Common Table Expression)
WITH high_spenders AS (
  SELECT user_id, SUM(amount) AS total
  FROM orders
  GROUP BY user_id
  HAVING SUM(amount) > 1000
)
SELECT users.name, high_spenders.total
FROM users
INNER JOIN high_spenders ON users.id = high_spenders.user_id;

-- Window functions
SELECT name, age,
  ROW_NUMBER() OVER (ORDER BY age DESC) AS rank,
  AVG(age) OVER () AS avg_age,
  age - LAG(age) OVER (ORDER BY age) AS age_diff
FROM users;
06

Indexes & Performance

Speed up queries with indexes. B-tree, hash, composite. EXPLAIN shows the query plan.

๐Ÿง  Note for the confused:
Indexes make queries faster by keeping a sorted copy of specific columns. It's like having an index at the back of a textbook. Instead of reading the whole book to find 'JavaScript', you just check the index. Databases are lazy too.
-- Create index
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_age ON users(age);

-- Composite index
CREATE INDEX idx_orders_user_date ON orders(user_id, order_date);

-- Unique index
CREATE UNIQUE INDEX idx_users_email_unique ON users(email);

-- Analyze query
EXPLAIN ANALYZE
SELECT * FROM users WHERE email = 'mayank@test.com';

-- Partial index
CREATE INDEX idx_active_users ON users(id)
WHERE active = true;

-- Drop index
DROP INDEX idx_users_email;
07

Transactions & Constraints

BEGIN/COMMIT/ROLLBACK. ACID. Primary keys, foreign keys, unique, check constraints.

๐Ÿง  Note for the confused:
Transactions are SQL's safety net. BEGIN starts a group of operations. If anything fails before COMMIT, ROLLBACK undoes everything. It's like a 'Ctrl+Z' for your database. But fancier.
-- Transaction
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;  -- or ROLLBACK on error

-- Constraints
CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(255) UNIQUE NOT NULL,
  age INT CHECK (age >= 0 AND age <= 150),
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE orders (
  id SERIAL PRIMARY KEY,
  user_id INT REFERENCES users(id) ON DELETE CASCADE,
  amount DECIMAL(10,2) NOT NULL CHECK (amount > 0)
);
08

Views & Stored Procedures

Views are saved queries. Stored procedures are saved SQL programs. Triggers fire on events.

๐Ÿง  Note for the confused:
Views are saved queries that pretend to be tables. It's like taking a really complicated recipe and taping it to your fridge as 'The Good Thing.' Just run the view and pretend you wrote all that SQL yourself.
-- View
CREATE VIEW active_users AS
SELECT * FROM users WHERE active = true;

SELECT * FROM active_users;

-- Stored procedure (PostgreSQL)
CREATE OR REPLACE FUNCTION get_user_count()
RETURNS INT AS $$
BEGIN
  RETURN (SELECT COUNT(*) FROM users);
END;
$$ LANGUAGE plpgsql;

SELECT get_user_count();

-- Trigger
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = CURRENT_TIMESTAMP;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER set_timestamp
BEFORE UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION update_timestamp();