What you'll practice: cutting a big result set down to exactly the rows you want with
WHERE, then layering on comparison operators (=,<,>,<>), logical operators (AND,OR,NOT), set membership (IN), range checks (BETWEEN), pattern matching (LIKE/ILIKE), null-handling (IS NULL), and pagination (LIMIT/OFFSET).
- Use
WHEREwith comparison operators to filter rows - Combine conditions with
AND,OR, and parentheses - Write set-membership filters with
INandNOT IN - Use
BETWEENfor inclusive range filters - Match text patterns with
LIKEand case-insensitiveILIKE - Handle
NULLcorrectly withIS NULL/IS NOT NULL - Paginate results with
LIMIT/OFFSET(and the SQL-standardFETCH FIRST ... ROWS ONLY)
psql -U postgres -d sql_exercise \
-f 02-sql-fundamentals/02-filtering-data/schema.sql
psql -U postgres -d sql_exercise \
-f 02-sql-fundamentals/02-filtering-data/seed.sqlThen from your psql prompt:
SET search_path TO sqlf_filtering;
SELECT COUNT(*) FROM person; -- expect 50Return every column for people whose country_of_origin is 'USA'.
Verify: eyeball the country column — they should all read USA.
Return first_name, last_name, and country_of_origin for every female person.
Hint: gender = 'F'.
Return everyone whose country_of_origin is not 'USA'.
Hint: the "not equal" operator in SQL is <> (or != in most dialects — both work in Postgres).
Return first_name, last_name, and dob for every person born strictly after 1990-01-01.
Question: does dob > '1990-01-01' include someone born on 1990-01-01? Why not?
Return everyone born on or after 1995-01-01.
Hint: >= is the "greater than or equal" operator.
Return every female person whose country_of_origin is 'Egypt'.
Hint: WHERE gender = 'F' AND country_of_origin = 'Egypt'.
Return everyone from either 'UK' or 'Canada'.
Bonus: do this with OR first, then rewrite it using IN — see exercise 9.
Return every female person from Egypt or Morocco.
Hint: without parentheses, WHERE gender = 'F' AND country_of_origin = 'Egypt' OR country_of_origin = 'Morocco' does not mean what you think. Wrap the OR in parentheses.
Verify: every row should have gender = 'F' and be from Egypt or Morocco — never a male from Morocco.
Return everyone whose country is one of: 'Pakistan', 'India', 'Bangladesh', 'Sri Lanka'.
Hint: country_of_origin IN (...).
Return everyone whose country is not one of 'USA', 'UK', 'Canada', 'Australia'.
Return everyone born between 1985-01-01 and 1995-12-31 (inclusive).
Hint: dob BETWEEN '1985-01-01' AND '1995-12-31'.
Question: is BETWEEN inclusive on both ends in PostgreSQL?
Return everyone whose first_name starts with the letter A.
Hint: first_name LIKE 'A%'. The % matches zero or more characters.
Return everyone whose last_name contains the letter a somewhere.
Hint: '%a%'.
Question: what if you also wanted matches on capital A? Read the next exercise.
Return everyone whose last_name contains 'a' in either case, using ILIKE.
Verify: compare your row count against exercise 13 — it should be larger (Smith, Ali, Khan, etc. all match differently).
Return every person whose phone_number ends in '0'. Use a LIKE pattern.
Hint: '%0'.
Return first_name, last_name, and phone_number for every person whose phone_number is missing.
Question: why doesn't WHERE phone_number = NULL work?
Return everyone who has an email on file.
Return everyone who is missing both their email and their phone number.
Hint: two IS NULL conditions joined with AND.
Return the first 10 people ordered alphabetically by last_name.
Hint: ORDER BY last_name LIMIT 10.
Return rows 11–20 (i.e. the second "page" of 10) when ordered alphabetically by last_name.
Hint: ORDER BY last_name LIMIT 10 OFFSET 10.
Rewrite exercise 19 using the SQL-standard FETCH FIRST n ROWS ONLY syntax instead of LIMIT.
Hint:
SELECT ... FROM person
ORDER BY last_name
FETCH FIRST 10 ROWS ONLY;Question: when would you prefer one syntax over the other?
Return the first 5 female people from countries starting with 'S', born after 1985-01-01, ordered by dob descending.
Hint: this is WHERE + AND + LIKE + ORDER BY ... DESC + LIMIT 5 all stacked.
Return everyone whose email ends with '@gmail.com'.
How many rows does SELECT COUNT(*) FROM person WHERE phone_number <> '020-555-0002'; return? Is it what you expected? (Hint: NULL <> anything is NULL, not TRUE.)
Return everyone whose first_name starts with 'Ma' using LIKE, and then rewrite the same query with SUBSTRING(first_name, 1, 2) = 'Ma'. Which one would run faster if first_name had an index?
DROP SCHEMA sqlf_filtering CASCADE;