Sling Academy
Home/MySQL/MySQL 8: Find the min/max value in each group

MySQL 8: Find the min/max value in each group

Last updated: January 26, 2024

Introduction

MySQL is a powerful open-source relational database management system often used for web database applications. As data analysis becomes increasingly important for decision-making, being able to manipulate and aggregate data efficiently is crucial. A common requirement is to find the minimum (MIN) or maximum (MAX) values within each group of data. In this tutorial, we will explore several methods of retrieving min/max values in grouped dataset in MySQL 8, starting from basic groupings to more advanced use cases.

Before we begin, ensure that you have MySQL 8 or higher installed, as some features addressed might not be available in earlier versions. Also, you should have a basic understanding of SQL, including SELECT statements, GROUP BY clauses, and aggregate functions.

Using GROUP BY to Find Min/Max Values

At its heart, the GROUP BY statement in SQL is used to arrange identical data into groups. The GROUP BY clause follows the WHERE clause in a SELECT statement and precedes the ORDER BY clause.


 SELECT column_name(s),
        MIN(column_name) as MinValue,
        MAX(column_name) as MaxValue
 FROM table_name
 GROUP BY column_name(s);
 

Let’s say we have a sales table called sales_data, and we want to find the minimum and maximum sale amounts made by each salesperson.


 SELECT salesperson_id,
        MIN(sale_amount) AS MinSale,
        MAX(sale_amount) AS MaxSale
 FROM sales_data
 GROUP BY salesperson_id;
 

This query returns the minimum and maximum sale amounts for each salesperson.

Window Functions for Min/Max Values

MySQL 8 introduced window functions that can compute aggregate values without collapsing the rows into a single output row per group. This is particularly useful when you want to display the entire row of data along with min or max value for reference.


 SELECT salesperson_id,
        sale_amount,
        MIN(sale_amount) OVER (PARTITION BY salesperson_id) AS MinSale,
        MAX(sale_amount) OVER (PARTITION BY salesperson_id) AS MaxSale
 FROM sales_data;
 

With the above query, each row will include information regarding the specific sale as well as the min/max sale amounts for that salesperson.

Advanced: Using Subqueries to Compute Min/Max

In more complex scenarios, you may need to select additional information that isn’t directly involved in the grouping or aggregates. Subqueries can help achieve this.


 SELECT s.salesperson_id,
        s.sale_amount,
        s.sale_date,
        m.MinSale,
        m.MaxSale
 FROM sales_data s
 JOIN (
     SELECT salesperson_id,
            MIN(sale_amount) as MinSale,
            MAX(sale_amount) as MaxSale
     FROM sales_data
     GROUP BY salesperson_id
 ) m ON s.salesperson_id = m.salesperson_id;
 

In this example, we’ve introduced a subquery that computes the min and max sales for each salesperson and then joined this result back to the original sales table to get the detailed records.

Exploring Group-wise Sorting Limitations

Sometimes, rather than grabbing the min/max aggregate, you want the entire row that holds this value. This can be a bit more complex and typically involves a subquery or a join.


 SELECT a.*
 FROM sales_data a
 INNER JOIN (
     SELECT salesperson_id,
            MIN(sale_amount) AS MinSale
     FROM sales_data
     GROUP BY salesperson_id
 ) as b ON a.salesperson_id = b.salesperson_id AND a.sale_amount = b.MinSale;
 

This query gets the rows from sales_data with the minimum sale for each salesperson. The inner subquery finds the minimum sale per salesperson, and then it is joined against the original table to get the full row details of only those min sale records.

Conclusion

Finding the minimum or maximum value in each group using MySQL 8 provides various avenues to display and use your data effectively. Whether using basic groupings, window functions for added row details or intricate subqueries and joins for complex scenarios, MySQL 8’s functionality caters to a broad array of data analysis objectives.

Next Article: MySQL 8: Find the sum/average of values in each group

Previous Article: MySQL 8: Count rows in each group with GROUP BY and COUNT

Series: MySQL Tutorials: From Basic to Advanced

MySQL

You May Also Like

  • MySQL: How to reset the AUTO_INCREMENT value of a table
  • MySQL: How to add a calculated column to SELECT query
  • MySQL: Eliminate orphan rows in one-to-many relationships
  • MySQL: Using R-Tree Indexes for Spatial Data Types
  • How to Create Custom Collations in MySQL
  • Using Hash Indexes in MySQL: A Practical Guide
  • Understanding Full-Text Indexes in MySQL
  • Partial Indexes in MySQL: A Practical Guide
  • MySQL: How to Remove FOREIGN KEY Constraints
  • Using ENUM in MySQL 8: A Practical Guide (with Examples)
  • MySQL: Creating a Fixed-Size Table by Using Triggers
  • One-to-Many Relationship in MySQL 8: A Practical Guide
  • Using Regular Expressions in MySQL 8: The Complete Guide
  • Using Loops in MySQL: A Practical Guide (with Examples)
  • How to Execute an SQL File in VS Code
  • Making use of the JSON_REMOVE() function in MySQL 8
  • MySQL 8: How to count rows in related tables
  • Replication in MySQL 8: A Comprehensive Guide
  • MySQL 8: FIRST_VALUE(), LAST_VALUE(), and NTH_VALUE() functions – Explained with examples