N015-H3 Tier 2 · Core SQL · hard ecommerce · Brightlane

Return each such status and its order count

Part of HAVING in SQL

The problem

Brightlane's operations team is investigating order-status distribution anomalies and needs to flag statuses that have exactly 11 orders on record.

Write a query to return each such status and its order count.

Assumptions:

  • The orders table contains every order Brightlane has processed.
  • The match is on equality with 11, not a range — a status with 10 or 12 orders does not qualify.

Output:

  • One row per status whose count is exactly 11, with columns status and order_count.
Schema · ecommerce 5 tables
categories
id integer
name text
parent_id? integer
products
id integer
name text
category_id integer
price numeric
stock_qty integer
attributes? jsonb
order_items
id integer
order_id integer
product_id integer
quantity integer
unit_price numeric
customers
id integer
name text
email text
city? text
country text
created_at timestamptz
is_active boolean
orders
id integer
customer_id integer
ordered_at timestamptz
status text
total_amount numeric

Run previews · Check grades

Write a query, then run it to see results here.

Worked solution Try it yourself first
Solution query
SELECT
  status,
  COUNT(*) AS order_count
FROM
  orders
GROUP BY
  status
HAVING
  COUNT(*) = 11

The shape

HAVING COUNT(*) = 11 is an equality filter on the group's row count. GROUP BY status builds one row per distinct status with that status's count alongside; HAVING keeps only the rows whose count equals exactly 11. cancelled and pending both land at 11 and survive. delivered, with its much larger count, fails the equality and drops out: the comparison is =, not >=.

Clause by clause

  • SELECT status, COUNT(*) AS order_count returns each surviving status with its order count. COUNT(*) reads every row in the group and returns the size.
  • FROM orders is the source set.
  • GROUP BY status partitions the orders into one group per status value. After this clause, each row in the working set represents one status with its order count aggregated behind it.
  • HAVING COUNT(*) = 11 filters those status rows by exact-count equality. Statuses whose count is anything other than 11 (10, 12, 200) all drop out together. The operator matters more than the literal: > would have produced a different result set, and so would >=.

Why this and not > 10

A natural temptation is to read "exactly 11" as "at least 11" and reach for > 10 or >= 11. Those produce a wider result set. Any status with 11 or more orders would qualify, including delivered at whatever its true count is. The anomaly-investigation framing is the tell: operations isn't asking for thresholds, they're asking for a specific count value. Statuses above or below 11 are not interesting.

Every comparison operator that works in WHERE works the same way in HAVING. =, <>, <, >, <=, >=. The only difference is what sits on the left side: in WHERE a raw row value, in HAVING an aggregate. The operator semantics are identical.

The trap

The trap is reflexive. HAVING lessons usually frame thresholds as "more than N" or "at least N," so equality on a count feels unusual and learners drift toward a >-style filter. The prompt's word "exactly" is doing real work: a status with 12 orders is not the same anomaly as one with 11. = is the right operator.

The rule: HAVING is not specifically a "greater than" filter. It's a filter on aggregate values, and any comparison operator can sit in it. Match the operator to the question.

You practiced an equality-based HAVING filter. Equality (=), inequality (<>), and ranges all work in HAVING exactly as they do in WHERE — the only difference is what's on the left side: aggregate values rather than raw column values.

How you actually get good at SQL

Reading explains SQL. Writing it, over and over with instant feedback, is what makes you fluent.

That's the whole SQLMaxx loop: 600+ real problems, instant AI feedback, mastery you can actually see, and spaced review that won't let you forget.

A stack of SQL practice problem cards, the top card showing an employees table.
615 problems · 66 concepts

Real problems. Not toy examples.

615 hand-built problems spanning all 66 concepts, from basic SELECTs to window functions, built on real schemas and real business questions, the kind you'll actually get asked on the job. Enough reps to make SQL automatic.

A retro computer showing a SQL query marked correct with a green checkmark.
Instant AI feedback

Write a query. Know if it's right in one second.

No copying an answer and hoping it clicked. The AI grader checks your real query against real data, catches exactly what's wrong, and explains the fix in plain English, like a senior analyst reading over your shoulder on every problem.

A circular mastery progress dial filling from blue to green, the SQLMaxx diamond at its center.
Mastery tracking

Stop guessing whether you actually know it.

SQLMaxx tracks every concept and shows you what you've mastered and what's still shaky. Your skills fill in one concept at a time, so 'I think I get joins' becomes something you can prove.

A SQL query editor circled by a blue return arrow with a clock, scheduled to come back for review.
Spaced review

Learn it once. Keep it for good.

Most of what you learn this week fades by next week. So when a concept comes due for review, SQLMaxx hands you a fresh problem to solve from a blank editor, not a flashcard to re-read. A research-backed spaced-repetition algorithm (FSRS) times each return for right before you'd forget, so your SQL is still there months later, when the interview or the job actually needs it.

Practice, feedback, mastery, review. That's the loop that turns reading into real skill.

Start free

No account, no credit card. Start solving in under a minute.