SQL
96 challenges · 0 mastered
SQL (Structured Query Language) is a standard language used to communicate with relational databases. It allows you to create, read, update, and delete data stored in tables.
SELECT * FROM employees;SQL is like giving instructions to a librarian — you tell them what book (data) you want, and they fetch it for you.
A Database is an organized collection of structured data stored electronically. A relational database stores data in tables with rows and columns.
CREATE DATABASE company_db;A database is like a filing cabinet. Each drawer is a table, each folder is a row, and each label is a column.
A Table is a collection of related data organized in rows (records) and columns (fields). Each table represents a specific entity like employees, products, or orders.
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(100),
department VARCHAR(50),
salary DECIMAL(10,2)
);A table is like a spreadsheet — columns are headers (name, salary) and rows are individual records.
A Primary Key is a column (or combination of columns) that uniquely identifies each row in a table. It cannot contain NULL values and must be unique.
CREATE TABLE users (
user_id INT PRIMARY KEY,
email VARCHAR(255) UNIQUE,
name VARCHAR(100)
);A Primary Key is like an Aadhaar number — no two people can have the same one.
A Foreign Key is a column that creates a relationship between two tables. It references the Primary Key of another table to enforce referential integrity.
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
amount DECIMAL(10,2),
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);A Foreign Key is like a reference letter — it points to someone (row) in another table.
DELETE removes specific rows and can use WHERE clause. TRUNCATE removes all rows but keeps the table structure. DROP removes the entire table including its structure.
DELETE FROM employees WHERE department = 'HR';
TRUNCATE TABLE temp_logs;
DROP TABLE old_records;DELETE = erase specific pages from a notebook. TRUNCATE = tear out all pages but keep the notebook. DROP = throw the entire notebook away.
WHERE filters rows before grouping. HAVING filters groups after the GROUP BY clause is applied. HAVING is used with aggregate functions.
-- WHERE: filter rows
SELECT * FROM employees WHERE salary > 50000;
-- HAVING: filter groups
SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) > 60000;WHERE filters individual students. HAVING filters entire classrooms based on average marks.
NULL represents a missing or unknown value. It is not the same as zero or an empty string. NULL comparisons require IS NULL or IS NOT NULL.
SELECT * FROM employees WHERE phone IS NULL;
SELECT * FROM employees WHERE phone IS NOT NULL;
-- This will NOT work as expected:
-- SELECT * FROM employees WHERE phone = NULL;NULL means 'I don't know the value' — not zero, not blank, just unknown.
CRUD stands for Create (INSERT), Read (SELECT), Update (UPDATE), and Delete (DELETE) — the four basic operations on database data.
-- Create
INSERT INTO employees (name, salary) VALUES ('Manav', 75000);
-- Read
SELECT * FROM employees;
-- Update
UPDATE employees SET salary = 80000 WHERE name = 'Manav';
-- Delete
DELETE FROM employees WHERE name = 'Manav';CRUD covers everything you can do with data: add it, view it, change it, or remove it.
SELECT retrieves data from one or more tables. It can return specific columns, filtered rows, sorted results, and aggregated data.
SELECT name, salary
FROM employees
WHERE department = 'Engineering'
ORDER BY salary DESC;SELECT is like asking a question: 'Show me all engineers sorted by salary.'
INSERT adds new rows into a table.
-- Single row
INSERT INTO products (name, price) VALUES ('Laptop', 75000);
-- Multiple rows
INSERT INTO products (name, price) VALUES
('Mouse', 500),
('Keyboard', 1200),
('Monitor', 15000);INSERT is like adding a new contact to your phone.
UPDATE modifies existing rows in a table. Always use a WHERE clause to avoid updating all rows accidentally.
UPDATE employees
SET salary = salary * 1.10
WHERE department = 'Engineering';UPDATE is like editing a saved contact's phone number.
DISTINCT removes duplicate rows from the result. GROUP BY groups rows for aggregate calculations like COUNT, SUM, AVG.
-- DISTINCT: unique departments
SELECT DISTINCT department FROM employees;
-- GROUP BY: count per department
SELECT department, COUNT(*) AS headcount
FROM employees
GROUP BY department;DISTINCT says 'show me unique values.' GROUP BY says 'group them and calculate something.'
WHERE filters rows based on a condition. Only rows that satisfy the condition are included in the result.
SELECT * FROM products WHERE price > 1000;
SELECT * FROM employees WHERE department = 'HR' AND salary > 50000;WHERE is like a filter on an e-commerce site — show only products above ₹1000.
ORDER BY sorts the result set by one or more columns. Default is ascending (ASC). Use DESC for descending.
SELECT name, salary FROM employees
ORDER BY salary DESC;
SELECT * FROM products
ORDER BY category ASC, price DESC;ORDER BY is like sorting search results by price — low to high or high to low.
LIKE is used for pattern matching in WHERE clause. % matches any sequence of characters. _ matches exactly one character.
-- Names starting with 'A'
SELECT * FROM employees WHERE name LIKE 'A%';
-- Names ending with 'kumar'
SELECT * FROM employees WHERE name LIKE '%kumar';
-- Exactly 5-letter names
SELECT * FROM employees WHERE name LIKE '_____';LIKE is like using wildcard search — 'A%' finds Amit, Anita, Arjun.
IN allows matching a column against a list of values instead of writing multiple OR conditions.
-- Instead of:
SELECT * FROM employees WHERE dept = 'HR' OR dept = 'IT' OR dept = 'Finance';
-- Use IN:
SELECT * FROM employees WHERE dept IN ('HR', 'IT', 'Finance');IN is a shorthand for 'match any of these values.'
BETWEEN filters values within a range (inclusive of both endpoints).
SELECT * FROM employees WHERE salary BETWEEN 40000 AND 80000;
SELECT * FROM orders WHERE order_date BETWEEN '2024-01-01' AND '2024-12-31';BETWEEN is like saying 'give me everything from 40K to 80K, including both.'
Aggregate Functions perform calculations on a set of values and return a single result. Common ones are COUNT, SUM, AVG, MIN, and MAX.
SELECT COUNT(*) AS total_employees FROM employees;
SELECT AVG(salary) AS avg_salary FROM employees;
SELECT MAX(salary) AS highest_salary FROM employees;
SELECT SUM(amount) AS total_sales FROM orders;Aggregate functions answer questions like 'how many?', 'what's the total?', 'what's the average?'
GROUP BY groups rows sharing the same value in specified columns and is used with aggregate functions to get per-group results.
SELECT department, COUNT(*) AS headcount, AVG(salary) AS avg_salary
FROM employees
GROUP BY department;GROUP BY is like organizing students by class and then counting how many are in each.
COUNT(*) counts all rows including those with NULL values. COUNT(column) counts only rows where that specific column is NOT NULL.
-- Counts all rows (including NULLs)
SELECT COUNT(*) FROM employees;
-- Counts only rows where phone is not NULL
SELECT COUNT(phone) FROM employees;COUNT(*) counts everyone. COUNT(phone) counts only those who have a phone number.
No. WHERE cannot filter on aggregate results. Use HAVING to filter after GROUP BY. WHERE filters rows before aggregation, HAVING filters groups after.
-- ❌ This will fail:
-- SELECT department FROM employees WHERE COUNT(*) > 5 GROUP BY department;
-- ✅ Correct:
SELECT department, COUNT(*) AS cnt
FROM employees
GROUP BY department
HAVING COUNT(*) > 5;WHERE works before grouping, HAVING works after grouping.
Common data types include INT (whole numbers), VARCHAR (variable-length text), DECIMAL (precise numbers), DATE (dates), BOOLEAN (true/false), and TEXT (long text).
CREATE TABLE products (
id INT,
name VARCHAR(100),
price DECIMAL(10,2),
is_active BOOLEAN,
created_at DATE,
description TEXT
);Data types define what kind of value a column can hold — number, text, date, etc.
Constraints are rules applied to columns to enforce data integrity. Common constraints are PRIMARY KEY, FOREIGN KEY, NOT NULL, UNIQUE, CHECK, and DEFAULT.
CREATE TABLE employees (
id INT PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(100) NOT NULL,
age INT CHECK (age >= 18),
status VARCHAR(20) DEFAULT 'active'
);Constraints are like rules on a form — 'this field is required', 'this must be unique.'
UNIQUE ensures that all values in a column are different. Unlike PRIMARY KEY, a table can have multiple UNIQUE columns, and UNIQUE allows one NULL (in most databases).
CREATE TABLE users (
id INT PRIMARY KEY,
email VARCHAR(255) UNIQUE,
phone VARCHAR(15) UNIQUE
);No two users can have the same email or phone number.
DEFAULT provides a fallback value when no value is supplied during INSERT.
CREATE TABLE orders (
id INT PRIMARY KEY,
status VARCHAR(20) DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);If you don't specify a status, it automatically becomes 'pending.'
CHECK ensures that values in a column satisfy a specific condition.
CREATE TABLE employees (
id INT PRIMARY KEY,
age INT CHECK (age >= 18 AND age <= 65),
salary DECIMAL(10,2) CHECK (salary > 0)
);CHECK is like form validation — 'age must be 18 or above.'
