SQL Fundamentals — CRUD
SQL (Structured Query Language) is used to interact with relational databases. Data is stored in tables with rows (records) and columns (fields).
Every application needs persistent data storage. SQL is the standard language for querying and manipulating that data across 50+ years of database history.
Every time your app reads or writes data: loading a user profile, saving a form, showing a list, updating a record, deleting an item.
SELECT reads data, INSERT creates records, UPDATE modifies them, DELETE removes them. WHERE filters results. ORDER BY sorts. LIMIT restricts count.
📚Key Terms
Table— Like a spreadsheet — rows are records, columns are fields
Primary Key— Unique identifier for each row, usually an auto-incrementing integer (SERIAL)
Foreign Key— Column referencing the primary key of another table — creates relationships
NULL— Absence of a value. Different from 0 or empty string. Use IS NULL to check for it
ACID— Atomicity, Consistency, Isolation, Durability — properties ensuring data integrity
Code Examples
#1CRUD operations
-- CREATE TABLECREATE TABLE users (id SERIAL PRIMARY KEY, -- auto-incrementing integername VARCHAR(100) NOT NULL, -- max 100 chars, requiredemail VARCHAR(255) UNIQUE NOT NULL, -- unique across all rowsrole VARCHAR(20) DEFAULT 'user', -- default valuecreated_at TIMESTAMP DEFAULT NOW() -- auto timestamp);-- INSERT (Create)INSERT INTO users (name, email)VALUES ('Ali Ahmed', 'ali@example.com');-- Insert multiple rowsINSERT INTO users (name, email, role) VALUES('Ahmed Khan', 'ahmed@example.com', 'admin'),('Sara Ali', 'sara@example.com', 'user');-- SELECT (Read)SELECT * FROM users; -- all columnsSELECT id, name, email FROM users; -- specific columnsSELECT * FROM users WHERE role = 'admin'; -- filterSELECT * FROM users WHERE age > 18 AND role = 'user';SELECT * FROM users WHERE email LIKE '%@gmail.com'; -- patternSELECT * FROM users ORDER BY created_at DESC; -- sort newest firstSELECT * FROM users ORDER BY name ASC LIMIT 10 OFFSET 20; -- pagination-- UPDATEUPDATE usersSET name = 'Ali Khan', role = 'admin'WHERE id = 1;-- ⚠️ ALWAYS use WHERE with UPDATE/DELETE or you affect ALL rows!UPDATE users SET role = 'user'; -- affects EVERY user (usually a bug)-- DELETEDELETE FROM users WHERE id = 1;DELETE FROM users WHERE created_at < NOW() - INTERVAL '30 days';
#2JOINs — combining tables
-- Setup: posts table references usersCREATE TABLE posts (id SERIAL PRIMARY KEY,title TEXT NOT NULL,content TEXT,user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,created_at TIMESTAMP DEFAULT NOW());-- INNER JOIN — only rows with matches in BOTH tablesSELECTusers.name,posts.title,posts.created_atFROM postsINNER JOIN users ON posts.user_id = users.id;-- Alias for cleaner syntaxSELECTu.name AS author,p.title,p.created_atFROM posts pJOIN users u ON p.user_id = u.idWHERE u.role = 'admin'ORDER BY p.created_at DESC;-- LEFT JOIN — ALL rows from left table + matching from right-- Users without posts will appear with NULL post columnsSELECTu.name,COUNT(p.id) AS post_countFROM users uLEFT JOIN posts p ON p.user_id = u.idGROUP BY u.id, u.nameORDER BY post_count DESC;-- SubquerySELECT * FROM usersWHERE id IN (SELECT DISTINCT user_id FROM postsWHERE created_at > NOW() - INTERVAL '7 days');
Practice This Concept
Open the playground, paste any example, and experiment. The best way to learn is by breaking things.
Open in Playground