DEV Community

Cover image for Learning SQL the Hard Way (On Purpose): Notes from CS50 + Practice
Md Enayetur Rahman
Md Enayetur Rahman

Posted on

Learning SQL the Hard Way (On Purpose): Notes from CS50 + Practice

CS50 SQL — Lecture Notes + Mini Query Cheatsheet

Last updated: 2025-10-14

These notes summarize key topics from CS50’s Introduction to Databases with SQL and pair each topic with a tiny, runnable query.
The examples assume a sample table longlist with columns like "title", "author", "year", "format", "translator", "rating", "votes", and "pages".


1) Foundations (DB vs Spreadsheet, CRUD, SQL Dialects)

  • Idea: Databases enable reliable Create, Read, Update, Delete at scale; SQL has vendor-specific dialects (SQLite, PostgreSQL, MySQL).
  • Try: a trivial query to confirm your SQL engine is alive.
-- Portable sanity check
SELECT 1 AS one;
Enter fullscreen mode Exit fullscreen mode

2) Tools & Setup (sqlite3, VS Code, leaving the shell)

  • Idea: Use the sqlite3 CLI or a client; exit with .quit (SQLite).
  • Try: Check your SQLite version (replace with SELECT version(); on Postgres).
-- SQLite
SELECT sqlite_version() AS "sqlite version";
Enter fullscreen mode Exit fullscreen mode

3) SQL Basics (SELECT columns, identifiers vs strings)

  • Idea: Double-quotes for identifiers (tables/columns), single-quotes for string literals.
  • Try: Select specific columns.
SELECT "title", "author"
FROM "longlist";
Enter fullscreen mode Exit fullscreen mode

4) Peeking at Data (LIMIT)

  • Idea: Preview a small slice.
  • Try:
SELECT "title"
FROM "longlist"
LIMIT 5;
Enter fullscreen mode Exit fullscreen mode

5) Filtering Rows (WHERE, AND/OR/NOT, NULLs, case rules)

  • Idea: Use comparisons and logical operators; LIKE is case‑insensitive in SQLite, = is case‑sensitive for strings.
  • Try A: Exact year
SELECT "title"
FROM "longlist"
WHERE "year" = 2023;
Enter fullscreen mode Exit fullscreen mode
  • Try B: Combined conditions
SELECT "title", "format"
FROM "longlist"
WHERE ("year" = 2022 OR "year" = 2023)
  AND "format" <> 'hardcover';
Enter fullscreen mode Exit fullscreen mode
  • Try C: NULL checks
SELECT "title"
FROM "longlist"
WHERE "translator" IS NULL;
Enter fullscreen mode Exit fullscreen mode

6) Pattern Matching (LIKE with % and _)

  • Idea: % = any string; _ = any single char.
  • Try A: Word anywhere in title
SELECT "title"
FROM "longlist"
WHERE "title" LIKE '%love%';
Enter fullscreen mode Exit fullscreen mode
  • Try B: Unknown character
SELECT "title"
FROM "longlist"
WHERE "title" LIKE 'P_re';
Enter fullscreen mode Exit fullscreen mode

7) Ranges (>, <, >=, <=, BETWEEN)

  • Idea: Prefer concise range syntax.
  • Try:
SELECT "title", "year"
FROM "longlist"
WHERE "year" BETWEEN 2019 AND 2022;
Enter fullscreen mode Exit fullscreen mode

8) Sorting (ORDER BY ASC/DESC, multi-column tiebreaks)

  • Idea: Default is ASC; add DESC; chain multiple columns.
  • Try:
SELECT "title", "rating", "votes"
FROM "longlist"
ORDER BY "rating" DESC, "votes" DESC
LIMIT 10;
Enter fullscreen mode Exit fullscreen mode

9) Aggregations (AVG, MIN, MAX, SUM, COUNT) + ROUND + AS

  • Idea: Aggregate rows to one value; alias for readability.
  • Try:
SELECT ROUND(AVG("rating"), 2) AS "average rating"
FROM "longlist";
Enter fullscreen mode Exit fullscreen mode

10) Distinct Values (DISTINCT, COUNT DISTINCT)

  • Idea: De-duplicate before counting.
  • Try:
SELECT COUNT(DISTINCT "publisher") AS "publisher_count"
FROM "longlist";
Enter fullscreen mode Exit fullscreen mode

11) Data Types & Style Notes (readability, comparisons)

  • Idea: Uppercase SQL keywords; be mindful of type + case rules.
  • Try (case behavior demo in SQLite):
-- Case-sensitive equality (likely returns 0 rows if stored as 'Pyre')
SELECT "title"
FROM "longlist"
WHERE "title" = 'pyre';

-- Case-insensitive LIKE
SELECT "title"
FROM "longlist"
WHERE "title" LIKE 'pyre';
Enter fullscreen mode Exit fullscreen mode

12) Next Steps (Inspect schema; moving to multi-table models)

  • Idea: Learn table shapes, then model relations (authors, books, publishers).
  • Try (SQLite schema peek):
PRAGMA table_info("longlist");
Enter fullscreen mode Exit fullscreen mode
  • Try (PostgreSQL variant):
-- PostgreSQL: view columns for a table
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'longlist';
Enter fullscreen mode Exit fullscreen mode

Notes

  • Replace "longlist"/column names with your real schema.
  • For PostgreSQL, prefer single-quoted identifiers only when you’ve created them quoted; otherwise use unquoted snake_case identifiers.

Happy querying!

Top comments (0)