Free tutorials & notes in Hindi & English · Clean code examples · Mobile friendly learning
MySQL + SQL · Lesson 57

GROUP BY and HAVING

How a Grouped Query Works

A useful logical sequence is FROM → WHERE → GROUP BY → aggregate calculations → HAVING → SELECT → ORDER BY → LIMIT. The optimizer may execute differently, but results follow these semantics.

Verified dataset: Aarav (X-A, 86.50, Active), Meera (X-A, 91.00, Active), Kabir (X-B, 74.00, Inactive) and Sana (X-B, 88.50, Active). Total marks = 340.00 and overall average = 85.00.

GROUP BY: One Summary per Class

SELECT class_name,
       COUNT(*) AS students,
       SUM(marks) AS total_marks,
       ROUND(AVG(marks), 2) AS average_marks
FROM students
GROUP BY class_name
ORDER BY class_name;
X-A | 2 | 177.50 | 88.75 X-B | 2 | 162.50 | 81.25

All rows with the same class_name form one group. Grouping does not automatically sort; ORDER BY is explicit.

HAVING Filters Completed Groups

SELECT class_name,
       ROUND(AVG(marks), 2) AS average_marks
FROM students
GROUP BY class_name
HAVING AVG(marks) >= 85
ORDER BY class_name;
X-A | 88.75

HAVING is evaluated after group aggregates exist. Repeat the aggregate expression for portable clarity; MySQL also permits many select aliases in HAVING.

WHERE vs HAVING Together

SELECT class_name,
       COUNT(*) AS active_students,
       ROUND(AVG(marks), 2) AS active_average
FROM students
WHERE status = 'Active'
GROUP BY class_name
HAVING COUNT(*) >= 2
ORDER BY class_name;
X-A | 2 | 88.75

WHERE removes inactive Kabir first. X-B then has only Sana, so HAVING removes the one-student group.

Multiple Grouping Columns and ROLLUP

SELECT class_name, status, COUNT(*) AS students
FROM students
GROUP BY class_name, status
ORDER BY class_name, status;

SELECT class_name, COUNT(*) AS students
FROM students
GROUP BY class_name WITH ROLLUP;

The first creates one group per class/status combination. WITH ROLLUP adds an overall summary row represented by a rollup NULL; use MySQL's GROUPING() when real NULL grouping values must be distinguished from rollup rows.

ONLY_FULL_GROUP_BY and Correct Results

-- Ambiguous and normally rejected
SELECT class_name, full_name, AVG(marks)
FROM students
GROUP BY class_name;

Which full_name should represent a class? There is no correct single answer. Add full_name to grouping, aggregate it intentionally, or remove it. Do not disable strict mode merely to make an ambiguous query run.

Every selected expression must be an aggregate, a grouping expression, or functionally dependent on the group key.

Practice

  1. Count students per status.
  2. Show only classes with average at least 82.
  3. Calculate active averages, then keep groups with two or more active students.
  4. Create class/status groups.
  5. Add a rollup total and label it safely using GROUPING().

Quick Summary

  • GROUP BY creates one result per grouping combination.
  • WHERE filters rows first; HAVING filters groups later.
  • ORDER BY remains separate from grouping.
  • ONLY_FULL_GROUP_BY protects against ambiguous results.
  • WITH ROLLUP adds higher-level summaries.

Official References

References reviewed 14 August 2026.

Frequently Asked Questions

What does GROUP BY do?
It partitions filtered rows into groups sharing the same grouping values, then aggregate functions return one summary per group.
What is the difference between WHERE and HAVING?
WHERE filters rows before grouping. HAVING filters grouped results after aggregates are calculated.
Can HAVING be used without GROUP BY?
Yes. The entire filtered input can act as one group, but use HAVING only when a post-aggregation condition expresses the real intent.
Why does ONLY_FULL_GROUP_BY reject my query?
A selected nonaggregate column is not in GROUP BY and is not functionally dependent on grouped columns, so its value would be ambiguous.
What does WITH ROLLUP do?
It adds super-aggregate summary rows to a grouped result, such as an overall total after class totals.
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.