20 SQL Practice Problems for Beginners with Solutions
New to SQL? This practice set is designed for complete beginners. You'll work through 20 problems covering the five most fundamental SQL concepts — SELECT, WHERE, ORDER BY, LIMIT, and COUNT — with full solutions and plain-English explanations for every problem. No prior experience needed. Click any problem to reveal the solution.
Part 1 — SELECT (Problems 1–3)
SELECT is the first clause in almost every SQL query. It tells the database which columns you want to see. Think of it like choosing which columns to display from a spreadsheet.
Solution
SELECT item_name, price_usd FROM menu_items;
Explanation
SELECT tells the database which columns to return. By listing item_name and price_usd, only those two columns appear in the results — all other columns like category and calories are left out. FROM tells the database which table to pull from.
Solution
SELECT * FROM menu_items;
Explanation
The asterisk (*) is a shorthand that means "give me every column." This is useful when you're exploring a table for the first time and want to see all the data. Every row and every column in the table will be returned.
Solution
SELECT first_name, last_name, email FROM customers;
Explanation
Listing three column names after SELECT tells the database to return only those three columns for every row. The customer_id, signup_date, and city columns are excluded from the results because they weren't listed.
Part 2 — WHERE (Problems 4–6)
WHERE filters the rows returned by a query. Without it, you get every row in the table. Adding WHERE lets you say "only show me rows where this condition is true."
Solution
SELECT * FROM menu_items WHERE category = 'Dessert';
Explanation
WHERE category = 'Dessert' tells the database to only return rows where the category column equals 'Dessert'. Every other row is filtered out. Notice the text value is wrapped in single quotes — this is required for text comparisons in SQL.
Solution
SELECT * FROM customers WHERE city = 'New York';
Explanation
WHERE city = 'New York' filters the results so only customers from New York are returned. All customers from other cities are excluded. SELECT * means all columns are shown for the matching rows.
Solution
SELECT * FROM products WHERE price_usd > 50;
Explanation
WHERE price_usd > 50 filters to only rows where the price is greater than 50. Notice there are no quotes around the number — in SQL, quotes are only used for text values, never for numbers. Every product priced at $50 or less is excluded.
Part 3 — ORDER BY (Problems 7–9)
By default SQL returns rows in no particular order. ORDER BY lets you sort the results by any column — either ascending (A to Z, smallest to largest) or descending (Z to A, largest to smallest).
Solution
SELECT product_name, price_usd FROM products ORDER BY price_usd;
Explanation
ORDER BY price_usd sorts the results by price. When you don't specify ASC or DESC, SQL defaults to ascending order — meaning the lowest price appears first. This is the correct behavior for "cheapest to most expensive."
Solution
SELECT first_name, signup_date FROM customers ORDER BY signup_date DESC;
Explanation
ORDER BY signup_date DESC sorts dates in descending order — most recent first, oldest last. Without DESC, the oldest signup date would appear first. Always add DESC when you want newest, largest, or highest values at the top.
Solution
SELECT item_name, category FROM menu_items ORDER BY item_name;
Explanation
ORDER BY item_name sorts text columns alphabetically from A to Z by default. This makes it easy to scan through menu items in alphabetical order. If you wanted Z to A, you'd add DESC.
Part 4 — LIMIT (Problems 10–12)
LIMIT restricts how many rows are returned by a query. It's useful when a table has thousands of rows and you only need to see a few — for example, the top 5 results or just a quick sample of the data.
Solution
SELECT * FROM products LIMIT 5;
Explanation
LIMIT 5 tells the database to stop returning rows after the first 5. This is useful when you just want a quick look at what a table contains without retrieving thousands of rows. SELECT * returns all columns for those 5 rows.
Solution
SELECT item_name, price_usd FROM menu_items ORDER BY price_usd DESC LIMIT 3;
Explanation
ORDER BY price_usd DESC sorts all items from most to least expensive first. Then LIMIT 3 keeps only the top 3 rows from that sorted result. This ORDER BY + LIMIT combination is the standard pattern for finding the top N results in SQL.
Solution
SELECT first_name, signup_date FROM customers ORDER BY signup_date DESC LIMIT 10;
Explanation
ORDER BY signup_date DESC puts the most recent signups at the top. LIMIT 10 then keeps only the first 10 rows from that sorted list — giving you the 10 most recently signed up customers.
Part 5 — COUNT (Problems 13–15)
COUNT is an aggregate function that counts the number of rows in a table or group. It's one of the most commonly used functions in SQL and is often combined with WHERE to count rows that meet a specific condition.
Solution
SELECT COUNT(*) AS total_customers FROM customers;
Explanation
COUNT(*) counts every row in the table regardless of what values the columns contain. AS total_customers gives the result a readable column name instead of just showing "COUNT(*)". The result is a single number — the total number of rows in the customers table.
Solution
SELECT COUNT(*) AS electronics_count FROM products WHERE category = 'Electronics';
Explanation
WHERE category = 'Electronics' filters the rows first, keeping only Electronics products. COUNT(*) then counts how many rows remain after that filter. Combining WHERE with COUNT is how you count rows that meet a specific condition.
Solution
SELECT COUNT(*) AS affordable_items FROM menu_items WHERE price_usd < 10;
Explanation
WHERE price_usd < 10 filters to only rows where the price is below $10. COUNT(*) counts how many rows match that condition. The result is a single number telling you how many menu items are priced under $10.
Part 6 — Combined (Problems 16–20)
Real SQL queries almost always combine multiple clauses. These problems combine two of the concepts you've just practiced. Try to write the query before revealing the solution — you have everything you need.
Solution
SELECT item_name, price_usd FROM menu_items WHERE calories < 500;
Explanation
SELECT chooses which columns to display — just item_name and price_usd. WHERE calories < 500 filters the rows so only low-calorie items appear. The calories column itself doesn't need to be in your SELECT list to use it as a filter condition.
Solution
SELECT * FROM products WHERE category = 'Clothing' ORDER BY price_usd DESC;
Explanation
WHERE category = 'Clothing' filters to only Clothing products. ORDER BY price_usd DESC then sorts those filtered results from most to least expensive. The clause order matters — WHERE always comes before ORDER BY.
Solution
SELECT item_name, calories FROM menu_items ORDER BY calories LIMIT 5;
Explanation
ORDER BY calories sorts all items from lowest to highest calorie count. LIMIT 5 then keeps only the first 5 rows from that sorted list — giving the 5 lowest-calorie items. No DESC is needed here because we want the lowest values first, which is the default ascending order.
Solution
SELECT COUNT(*) AS chicago_customers FROM customers WHERE city = 'Chicago';
Explanation
WHERE city = 'Chicago' filters to only Chicago customers. COUNT(*) then counts how many rows match. The result is a single number — the total count of customers from Chicago. AS chicago_customers gives the result column a clear, readable name.
Solution
SELECT product_name, price_usd FROM products WHERE category = 'Electronics' ORDER BY price_usd DESC LIMIT 3;
Explanation
This query uses three clauses together. WHERE category = 'Electronics' filters to only Electronics products. ORDER BY price_usd DESC sorts those products from most to least expensive. LIMIT 3 keeps only the top 3 from that sorted list. This is a great example of how SQL clauses build on each other — filter first, sort second, limit third.
Ready to practice writing these queries yourself? Try the SQL Drills interactive beginner exercises — write real queries and get instant feedback.
Try Beginner Exercises Interactively →Feeling confident with the basics? Try the intermediate SQL exercises next, or head back to the SQL Drills Learn hub for more practice sets and guides.