SolveWithSQL

SQL Beginner Challenge 24: Filtering Rows vs Groups (WHERE + HAVING)

Difficulty: Beginner → Early Intermediate
Estimated time: 15–20 minutes
SQL concepts: WHERE, GROUP BY, HAVING, COUNT()
Goal: Understand when to filter rows and when to filter groups.

The Challenge

The product manager asks:

“Which categories have at least 2 products that cost more than 50?”

This question looks simple—but it requires a two-step filtering process.

You must:

  1. Filter individual rows based on price
  2. Then filter groups of rows based on how many remain

This is where many SQL learners get stuck.

Database Table

products

column_nametypedescription
product_idINTEGERUnique product ID
nameTEXTProduct name
categoryTEXTProduct category
priceDECIMALProduct price

Sample Data

product_idnamecategoryprice
101Wireless MouseAccessories24.99
102Mechanical KeyboardAccessories89.00
103WebcamAccessories59.99
104MonitorDisplays229.99
105USB-C HubAccessories34.50
106Laptop StandWorkspace39.99

Your Task

Write a SQL query that returns:

  • Each category
  • That has at least 2 products
  • Where each counted product costs more than 50

Expected Output

category
Accessories

(Mechanical Keyboard + Webcam)

Constraints

  • Use WHERE to filter rows
  • Use GROUP BY
  • Use HAVING to filter groups
  • Use COUNT()
  • Do not use SELECT *

Hint (Optional)

Remember:

  • WHERE runs before grouping
  • HAVING runs after grouping

They are not interchangeable.

SELECT
category
FROM products
WHERE price > 50
GROUP BY category
HAVING COUNT(*) >= 2;

Explanation

Let’s break this down step by step:

  1. WHERE price > 50
    Filters out products that don’t meet the price requirement.
  2. GROUP BY category
    Groups the remaining products by category.
  3. HAVING COUNT(*) >= 2
    Keeps only categories with at least two qualifying products.

This pattern is extremely common in analytics and reporting.

The Key Mental Model (Very Important)

WHERE → filters individual rows
GROUP BY → creates groups
HAVING → filters groups

Once this clicks, a large class of SQL problems becomes much easier.

Common Mistakes

  1. Using HAVING instead of WHERE HAVING price > 50 ❌ Invalid — HAVING works on aggregates, not raw rows.
  2. Filtering after grouping
    SQL does not work that way.
  3. Trying to combine everything into one clause

Optional Extension (Mini Bonus)

Try answering these variations:

  1. Which categories have at least 3 products costing more than 30?
  2. Which categories have only one expensive product?
  3. Sort the result alphabetically by category name.

Why this challenge matters

This challenge teaches one of the most important SQL distinctions:

Rows are filtered with WHERE.
Groups are filtered with HAVING.

If learners understand this, they’re ready for real-world analytics work.

Next Challenge

Beginner Challenge #25: Summing Values with SUM()

🔗 View reference solution on GitHub
(After you’ve tried the challenge)

Want more practical SQL challenges?
Subscribe to the Solve With SQL newsletter and get new problems delivered to your inbox.