Lesson 45 of 60 – MySQL GROUP BY
75%

MySQL GROUP BY

The GROUP BY clause is used to group rows that have the same values into summary rows. It is commonly used with aggregate functions such as COUNT(), SUM(), AVG(), MAX(), and MIN().

Note: GROUP BY is very useful for creating course-wise, month-wise, city-wise, department-wise, and category-wise reports.

1. What is GROUP BY?

The GROUP BY clause groups rows that have the same value in one or more columns.

SELECT course
FROM students
GROUP BY course;

This returns one row for each different course.

2. Why Use GROUP BY?

GROUP BY is useful when you want summarized information for different categories.

  • Number of students in each course
  • Total fees for each course
  • Average marks for each class
  • Total sales for each month
  • Number of employees in each department
  • Total payments from each student

3. Basic GROUP BY Syntax

The basic syntax is:

SELECT column_name, aggregate_function(column_name)
FROM table_name
GROUP BY column_name;

Example:

SELECT course, COUNT(*)
FROM students
GROUP BY course;

4. GROUP BY with COUNT()

COUNT() can be used with GROUP BY to count rows in each group.

SELECT
    course,
    COUNT(*) AS total_students
FROM students
GROUP BY course;

This returns the number of students enrolled in each course.

5. GROUP BY with SUM()

SUM() can be used to calculate the total value for each group.

SELECT
    course,
    SUM(fee) AS total_fee
FROM students
GROUP BY course;

This calculates the total fee for every course.

6. GROUP BY with AVG()

AVG() can calculate the average value for every group.

SELECT
    course,
    AVG(fee) AS average_fee
FROM students
GROUP BY course;

Each course will have its own average fee.

7. GROUP BY with MAX()

MAX() can find the highest value in each group.

SELECT
    course,
    MAX(fee) AS highest_fee
FROM students
GROUP BY course;

This returns the highest fee for each course.

8. GROUP BY with MIN()

MIN() can find the lowest value in each group.

SELECT
    course,
    MIN(fee) AS lowest_fee
FROM students
GROUP BY course;

This returns the lowest fee for each course.

9. GROUP BY with Multiple Aggregate Functions

You can use several aggregate functions in the same GROUP BY query.

SELECT
    course,
    COUNT(*) AS total_students,
    SUM(fee) AS total_fee,
    ROUND(AVG(fee), 2) AS average_fee,
    MAX(fee) AS highest_fee,
    MIN(fee) AS lowest_fee
FROM students
GROUP BY course;

This creates a complete course-wise summary.

10. GROUP BY with WHERE

WHERE filters rows before GROUP BY creates groups.

SELECT
    course,
    COUNT(*) AS total_students
FROM students
WHERE status = 'Active'
GROUP BY course;

This counts only active students in each course.

11. GROUP BY with ORDER BY

ORDER BY can be used to sort grouped results.

SELECT
    course,
    COUNT(*) AS total_students
FROM students
GROUP BY course
ORDER BY total_students DESC;

This displays courses from the highest number of students to the lowest.

12. GROUP BY Multiple Columns

You can group by more than one column.

SELECT
    course,
    gender,
    COUNT(*) AS total_students
FROM students
GROUP BY course, gender;

This creates groups based on the combination of course and gender.

13. GROUP BY Course and City

Multiple columns can be used for detailed reports.

SELECT
    course,
    city,
    COUNT(*) AS total_students
FROM students
GROUP BY course, city;

This shows the number of students for each course and city combination.

14. GROUP BY with DISTINCT Values

GROUP BY automatically produces one group for each distinct combination of the grouped columns.

SELECT course
FROM students
GROUP BY course;

This returns each course once.

For simply listing unique values, DISTINCT can also be used:

SELECT DISTINCT course
FROM students;

15. GROUP BY with Date Values

Date functions can be used with GROUP BY to create time-based reports.

SELECT
    YEAR(admission_date) AS admission_year,
    COUNT(*) AS total_students
FROM students
GROUP BY YEAR(admission_date);

This creates a year-wise student report.

16. Month-wise GROUP BY

You can group records by month using MONTH().

SELECT
    MONTH(payment_date) AS payment_month,
    SUM(amount) AS total_collection
FROM payments
GROUP BY MONTH(payment_date);

This calculates total payment collection for each month number.

17. Year and Month-wise GROUP BY

For reports covering multiple years, group by both year and month.

SELECT
    YEAR(payment_date) AS payment_year,
    MONTH(payment_date) AS payment_month,
    SUM(amount) AS total_collection
FROM payments
GROUP BY
    YEAR(payment_date),
    MONTH(payment_date)
ORDER BY
    payment_year,
    payment_month;

This prevents payments from the same month in different years from being combined.

18. GROUP BY with Aliases

Aliases make grouped results easier to understand.

SELECT
    course AS course_name,
    COUNT(*) AS student_count
FROM students
GROUP BY course;

The result will contain descriptive column names.

19. GROUP BY and NULL Values

If a grouped column contains NULL values, MySQL groups those NULL values together.

SELECT
    city,
    COUNT(*) AS total_students
FROM students
GROUP BY city;

If some students have no city value, they can appear together in a NULL group.

20. GROUP BY with Calculated Values

You can group using an expression or calculated value.

SELECT
    YEAR(admission_date) AS admission_year,
    COUNT(*) AS total_students
FROM students
GROUP BY YEAR(admission_date);

The grouping is based on the year extracted from admission_date.

21. GROUP BY with HAVING

HAVING filters groups after GROUP BY and aggregation.

SELECT
    course,
    COUNT(*) AS total_students
FROM students
GROUP BY course
HAVING COUNT(*) > 5;

This returns only courses containing more than five students.

HAVING will be covered in detail in the next lesson.

22. WHERE vs HAVING

WHERE HAVING
Filters individual rows Filters groups
Applied before GROUP BY Applied after GROUP BY
Commonly used with regular columns Commonly used with aggregate results

Example:

SELECT
    course,
    COUNT(*) AS total_students
FROM students
WHERE status = 'Active'
GROUP BY course
HAVING COUNT(*) > 5;

23. GROUP BY with SUM() and HAVING

You can filter groups according to their total value.

SELECT
    course,
    SUM(fee) AS total_fee
FROM students
GROUP BY course
HAVING SUM(fee) > 50000;

This displays only courses whose total fee is greater than 50000.

24. GROUP BY with AVG() and HAVING

HAVING can also filter groups according to their average.

SELECT
    course,
    AVG(marks) AS average_marks
FROM results
GROUP BY course
HAVING AVG(marks) >= 70;

This returns courses whose average marks are at least 70.

25. GROUP BY with JOIN

GROUP BY can be used after joining multiple tables.

SELECT
    c.course_name,
    COUNT(s.student_id) AS total_students
FROM courses c
LEFT JOIN students s
ON c.id = s.course_id
GROUP BY c.course_name;

This can show the number of students enrolled in each course.

26. Course-wise Fee Report

A practical fee report can be created using GROUP BY.

SELECT
    course,
    COUNT(*) AS students,
    SUM(total_fee) AS total_fee,
    SUM(paid_fee) AS paid_fee,
    SUM(total_fee - paid_fee) AS total_due
FROM students
GROUP BY course;

This creates a course-wise fee summary.

27. Student-wise Payment Report

You can group payments by student.

SELECT
    student_id,
    COUNT(*) AS payment_count,
    SUM(amount) AS total_paid
FROM payments
GROUP BY student_id;

This shows how many payments each student has made and the total amount paid.

28. Sorting GROUP BY Results

Grouped results can be sorted using ORDER BY.

SELECT
    course,
    COUNT(*) AS total_students
FROM students
GROUP BY course
ORDER BY total_students DESC;

You can also sort by course name:

SELECT
    course,
    COUNT(*) AS total_students
FROM students
GROUP BY course
ORDER BY course ASC;

29. GROUP BY Query Processing Order

A simplified logical order for a grouped query is:

FROM
WHERE
GROUP BY
HAVING
SELECT
ORDER BY

For example:

SELECT
    course,
    COUNT(*) AS total_students
FROM students
WHERE status = 'Active'
GROUP BY course
HAVING COUNT(*) > 5
ORDER BY total_students DESC;

Understanding this order helps you decide where each condition belongs.

30. Practical GROUP BY Example

CREATE TABLE students (
    student_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    course VARCHAR(100),
    city VARCHAR(100),
    fee DECIMAL(10,2),
    status VARCHAR(20)
);

INSERT INTO students
(name, course, city, fee, status)
VALUES
('Amit Kumar', 'Python', 'Patna', 15000, 'Active'),
('Priya Singh', 'Java', 'Patna', 18000, 'Active'),
('Rahul Sharma', 'Python', 'Gaya', 12000, 'Active'),
('Neha Kumari', 'PHP', 'Patna', 10000, 'Inactive'),
('Ravi Kumar', 'Python', 'Gaya', 15000, 'Active'),
('Pooja Singh', 'Java', 'Patna', 16000, 'Active');

-- Course-wise student count
SELECT
    course,
    COUNT(*) AS total_students
FROM students
GROUP BY course;

-- Course-wise total fee
SELECT
    course,
    SUM(fee) AS total_fee
FROM students
GROUP BY course;

-- Course-wise average fee
SELECT
    course,
    ROUND(AVG(fee), 2) AS average_fee
FROM students
GROUP BY course;

-- City-wise student count
SELECT
    city,
    COUNT(*) AS total_students
FROM students
GROUP BY city;

-- Active students by course
SELECT
    course,
    COUNT(*) AS active_students
FROM students
WHERE status = 'Active'
GROUP BY course;

-- Courses having more than one active student
SELECT
    course,
    COUNT(*) AS active_students
FROM students
WHERE status = 'Active'
GROUP BY course
HAVING COUNT(*) > 1
ORDER BY active_students DESC;

This practical example demonstrates course-wise, city-wise, and status-wise grouping along with aggregate functions, WHERE, HAVING, and ORDER BY.

📌 Key Points

  • GROUP BY combines rows with the same values into groups.
  • GROUP BY is commonly used with aggregate functions.
  • COUNT() can count rows in each group.
  • SUM() can calculate totals for each group.
  • AVG() can calculate averages for each group.
  • MAX() and MIN() can find highest and lowest values in each group.
  • Multiple columns can be used with GROUP BY.
  • WHERE filters rows before grouping.
  • HAVING filters groups after grouping.
  • ORDER BY can sort grouped results.
  • GROUP BY is useful for course-wise, city-wise, month-wise, and year-wise reports.
  • GROUP BY can be combined with JOINs.
  • GROUP BY is an important tool for creating database reports and dashboards.

🧠 Quick Quiz

Question: Which SQL clause is used to group rows with the same values?