What & Why
SQL is the language used to query relational databases. Every query starts with what you want (SELECT), where to get it (FROM), and — optionally — how to filter (WHERE), sort (ORDER BY), and cap the output (LIMIT). These four clauses cover 80% of day-to-day analytical work.
See how it works
Find the 5 most recently activated Pro users on Queryflo.
SELECT
id,
country,
channel,
activated_at
FROM growth.users
WHERE plan = 'pro'
AND activated_at IS NOT NULL
ORDER BY activated_at DESC
LIMIT 5;
Returns 5 rows — one per most-recently-activated Pro user, with their country, acquisition channel, and activation timestamp.
The four clauses
See explanation
SELECT — choose your columns. SELECT tells the database which columns to return.
-- Every column (use sparingly on large tables)
SELECT *
FROM growth.users;
-- Only what you need
SELECT id, country, plan
FROM growth.users;
-- Rename a column with AS
SELECT id, created_at AS joined_at
FROM growth.users;
*means "all columns" — fine for exploration, avoid in production code.ASgives a column an alias in the output — no effect on the underlying data.
WHERE — filter rows. WHERE keeps only the rows that match a condition.
SELECT id, country, plan
FROM growth.users
WHERE plan = 'pro';
Common operators:
| Operator | Example | Meaning |
|---|---|---|
= | plan = 'pro' | exact match |
!= or <> | plan != 'free' | not equal |
> / < | created_at > '2025-01-01' | greater / less than |
BETWEEN | created_at BETWEEN '2025-01-01' AND '2025-06-30' | inclusive range |
IN | plan IN ('pro','enterprise') | any of a list |
LIKE | country LIKE 'United%' | pattern match (% = wildcard) |
IS NULL | churned_at IS NULL | missing value |
Combine with AND / OR:
SELECT id, country
FROM growth.users
WHERE plan = 'pro'
AND churned_at IS NULL;
ORDER BY — sort the results.
SELECT id, country, activated_at
FROM growth.users
WHERE plan = 'pro'
ORDER BY activated_at DESC; -- most recently activated first
ASC(default) = smallest → largest.DESC= largest → smallest.- Sort on multiple columns:
ORDER BY country ASC, activated_at DESC.
LIMIT — cap the output.
SELECT id, country, activated_at
FROM growth.users
ORDER BY activated_at DESC
LIMIT 10; -- 10 most recently activated users
Always add LIMIT when exploring — it keeps queries fast and your results readable.
Practice this concept hands-on
Run SQL against real datasets right here in the browser and get instant AI feedback. Join the waitlist to get access.
Join the waitlist