Well-Attended Gym Classes

A gym wants to know which group classes have a real following. A class counts as popular when at least 4 different members have booked it. A member who books the same class many times still counts only once.

Return class_name and member_count (the number of different members who booked that class) for every popular class, one row per class, in any order. If no class reaches 4 members, return no rows.

Tables

class_bookings — One row per booking of a group class. The same member can book the same class on many dates.

ColumnTypeDescription
booking_id (key)INTEGERUnique booking id
class_nameTEXTName of the class, for example Spin or Pilates
member_idINTEGERMember who made the booking
class_dateTEXTDate of the session booked, 'YYYY-MM-DD'

Example

class_bookings

booking_idclass_namemember_idclass_date
1Spin112026-05-04
2Spin122026-05-04
3Spin112026-05-11
4Spin132026-05-11
5Spin112026-05-18
6Pilates122026-05-05
7Pilates142026-05-05
8Pilates152026-05-06
9Pilates112026-05-12
10Boxing162026-05-07
11Boxing172026-05-07

Expected output

class_namemember_count
Pilates4

Rows may be returned in any order. Your query also runs against hidden datasets with tricky edge cases.

SQL Path · Aggregation & Grouping · problem 13 of 70 · SQLite

You need one result row per class.
Repeat bookings by the same member must not inflate the count: COUNT accepts DISTINCT.
Filtering on an aggregate happens in HAVING.

The idea

Group the bookings by class_name so that each class becomes one row. Inside each group, COUNT(DISTINCT member_id) counts different members, ignoring how often each one booked. A plain COUNT(*) would count bookings, so one dedicated regular could make a class look busy.

The popularity rule is a condition on that aggregate, so it belongs in HAVING, which is evaluated after grouping. "At least 4" means >= 4. Using the same COUNT(DISTINCT ...) in both the SELECT list and HAVING keeps the displayed number and the filter consistent.

The alternative first removes repeat bookings with SELECT DISTINCT class_name, member_id, leaving one row per class-member pair. After that, a plain COUNT(*) per class is already a count of different members. This two-step version is handy in databases where COUNT(DISTINCT) is slow or when you need the deduplicated pairs for other calculations.

Solution

SELECT class_name,
       COUNT(DISTINCT member_id) AS member_count
FROM class_bookings
GROUP BY class_name
HAVING COUNT(DISTINCT member_id) >= 4;

Another way

SELECT class_name,
       COUNT(*) AS member_count
FROM (
  SELECT DISTINCT class_name, member_id
  FROM class_bookings
) AS attendees
GROUP BY class_name
HAVING COUNT(*) >= 4;

Why common answers fail

Counts bookings instead of different members, so one regular booking a class four times makes it look popular.

SELECT class_name, COUNT(*) AS member_count FROM class_bookings GROUP BY class_name HAVING COUNT(*) >= 4;

Uses > 4, so a class with exactly 4 members is left out although "at least 4" includes it.

SELECT class_name, COUNT(DISTINCT member_id) AS member_count FROM class_bookings GROUP BY class_name HAVING COUNT(DISTINCT member_id) > 4;

Shows distinct members but filters on the number of bookings, so repeat bookings still push small classes over the bar.

SELECT class_name, COUNT(DISTINCT member_id) AS member_count FROM class_bookings GROUP BY class_name HAVING COUNT(*) >= 4;

What the interviewer is checking

Tests GROUP BY with HAVING and whether you notice that rows (bookings) are not the same as entities (members).

Mistakes to avoid

  • Counting bookings instead of distinct members.
  • Using > instead of >= for "at least".
  • Filtering with a different expression from the one displayed.

Follow-ups to expect

  • Rank classes by member count. (ORDER BY member_count DESC or RANK() OVER)
  • Popular classes per month. (GROUP BY class_name, strftime('%Y-%m', class_date))
  • Members who booked every class. (relational division: HAVING COUNT(DISTINCT class_name) = total classes)

In real work

Product teams measure feature reach by distinct users rather than events, the same distinction between bookings and members.

Practice next

Next Post Previous Post
No Comment
Add Comment
comment url