SELECT is the R in CRUD — and the operation you'll run most.
1SELECT title, status -- which columns
2FROM tasks -- which table
3WHERE status = 'TODO' -- which rows
4ORDER BY due_date ASC -- in what order
5LIMIT 20; -- how manySQL executes roughly in this order: FROM → WHERE → SELECT → ORDER BY → LIMIT.
1SELECT id, title FROM tasks; -- ✅ explicit
2SELECT * FROM tasks; -- ⚠️ avoid in production codeSELECT * ships every column over the wire and breaks when the schema changes. Name your columns.
1WHERE status = 'DONE'
2WHERE due_date < now()
3WHERE status IN ('TODO', 'IN_PROGRESS')
4WHERE title ILIKE '%report%' -- case-insensitive contains
5WHERE due_date IS NULL -- never use = NULL
6WHERE status = 'TODO' AND due_date < now()1ORDER BY created_at DESC -- newest first
2LIMIT 10 OFFSET 20; -- page 3 of 10-per-page1SELECT status, COUNT(*) AS n
2FROM tasks
3GROUP BY status;GROUP BY collapses rows into buckets; aggregate functions (COUNT, SUM, AVG, MIN, MAX) summarize each bucket.
1SELECT t.title, u.name AS owner
2FROM tasks t
3JOIN users u ON u.id = t.owner_id
4WHERE t.status = 'TODO';A JOIN stitches rows from two tables together on a matching condition — here, the task's owner_id to the user's id.