SQL Fundamentals
SQL is the standard language for asking questions of a relational database and for changing its data. You describe the result you want, and the database decides how to compute it.
Reading data
SELECT name, price
FROM products
WHERE category = 'books' AND price < 20
ORDER BY price DESC
LIMIT 10;
SELECTchooses columns. AvoidSELECT *in application code, because it fetches more than needed and breaks when columns change.WHEREfilters rows. UseAND,OR,IN (...),BETWEEN,LIKEandIS NULL.ORDER BYsorts. Without it, the order of rows is not guaranteed.LIMIT(PostgreSQL, MySQL, SQLite) orTOP/FETCH FIRST(SQL Server) caps the number of rows.
Aggregating
SELECT category, COUNT(*) AS items, AVG(price) AS avg_price
FROM products
GROUP BY category
HAVING COUNT(*) > 5;
COUNT, SUM, AVG, MIN and MAX collapse many rows into one value per group. WHERE filters rows before grouping, HAVING filters groups afterwards.
Joining tables
SELECT c.name, o.id, o.total
FROM customers AS c
INNER JOIN orders AS o ON o.customer_id = c.id
WHERE o.total > 100;
INNER JOINkeeps only rows that match on both sides.LEFT JOINkeeps all rows from the left table and fillsNULLwhere there is no match. Use it to find “customers without orders”.
Changing data
INSERT, UPDATE and DELETE modify rows. Always include a WHERE on updates and deletes, and run it first as a SELECT to see which rows it would touch. Related changes belong in a transaction.
SQL injection
Never build SQL by pasting user input into a string. Use parameterized queries, which keep data separate from the command. See Common Vulnerabilities and Input Validation.
Things to explore later
Subqueries, UNION, window functions, views, and reading a query plan with EXPLAIN (see Indexing Basics).
Try it
Install SQLite (or use any local database) and create a products table with a few rows. Write one query each for: filtering and sorting, a group count per category, and a LEFT JOIN that finds rows with no match in a second table.
Common mistakes
- Running UPDATE or DELETE without a WHERE clause.
- Using SELECT * in application code.
- Relying on row order without an ORDER BY.
- Building SQL by concatenating user input.
Check yourself
- What is the difference between WHERE and HAVING?
- How would you find customers who have no orders?
- Why are parameterized queries safer than building a string?