Methods for Retrieving Distinct Column Values with Corresponding Data in MySQL

Nov 20, 2025 · Programming · 14 views · 7.8

Keywords: MySQL | GROUP BY | DISTINCT | Exclusion Join | Performance Optimization

Abstract: This article provides an in-depth exploration of various methods to retrieve unique values from a specific column along with their corresponding data from other columns in MySQL. It analyzes the special behavior and potential risks of GROUP BY statements, introduces alternative approaches including exclusion joins and composite IN subqueries, and discusses performance considerations and optimization strategies through practical examples and case studies.

Problem Background and Core Challenges

In database queries, there is often a need to retrieve unique values from a specific column while preserving the corresponding data from other columns. Using a user table as an example, assume the table structure includes ID, FirstName, and LastName columns, with sample data as follows:

ID   FirstName   LastName
1      John        Doe
2      Bugs        Bunny
3      John        Johnson

The objective is to obtain unique values from the FirstName column while displaying the corresponding ID and LastName. For instance, for the duplicate John entries, only one instance should be displayed, selecting the record with ID 1 and LastName Doe.

Basic Method: GROUP BY Statement

The most straightforward solution is to use the GROUP BY statement:

SELECT ID, FirstName, LastName FROM table_name GROUP BY FirstName

This approach works in MySQL but comes with significant limitations. MySQL allows non-aggregated columns in the SELECT clause without including them in the GROUP BY clause, in which case the server arbitrarily selects values from within the group. This behavior was default before MySQL 5.7.5 but is restricted by the ONLY_FULL_GROUP_BY SQL mode in later versions.

Potential Issues and Risks with GROUP BY

Using GROUP BY without specifying aggregate functions can lead to unpredictable results. The MySQL documentation explicitly states that under these circumstances, the server is free to choose any value within the group. Consider the following test case:

SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC

In MySQL 5.6, this query might return:

| ID | first |  last |
|----|-------|-------|
|  2 |  Bugs | Bunny |
|  1 |  John |   Doe |

Whereas using an ordered subquery:

SELECT * FROM (
    SELECT * FROM table_name ORDER BY ID DESC
) AS t1
GROUP BY FirstName

might yield different results:

| ID | first |    last |
|----|-------|---------|
|  2 |  Bugs |   Bunny |
|  3 |  John | Johnson |

This inconsistency highlights the unreliability of GROUP BY under specific configurations.

Alternative Approach 1: Exclusion Join Method

Exclusion Join provides a more controlled way to obtain unique values and their corresponding data. This method ensures deterministic results through self-joins and conditional filtering.

Unambiguous Entities Scenario

When the combination of FirstName and LastName is unique, the following query can be used to retrieve results ordered by last name in ascending order:

SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname > t2.lastname
WHERE t2.id IS NULL

This query returns:

| id | firstname | lastname |
|----|-----------|----------|
|  2 |      Bugs |    Bunny |
|  1 |      John |      Doe |

For descending order by last name:

SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname < t2.lastname
WHERE t2.id IS NULL

Returns:

| id | firstname | lastname |
|----|-----------|----------|
|  2 |      Bugs |    Bunny |
|  3 |      John |  Johnson |

Ambiguous Entities Scenario

When duplicate name combinations exist, it's necessary to introduce ID as an additional sorting criterion:

SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND (t1.lastname > t2.lastname
OR (t1.firstname = t1.firstname AND t1.lastname = t2.lastname AND t1.id > t2.id))
WHERE t2.id IS NULL

Alternative Approach 2: Composite IN Subquery

For large datasets, exclusion joins might perform poorly. Composite IN() subqueries offer another efficient solution.

Unambiguous Entities Scenario

Ascending order by last name:

SELECT t1.*
FROM table_name AS t1
WHERE (t1.firstname, t1.lastname) IN(
   SELECT firstname, MIN(lastname)
   FROM table_name
   GROUP BY firstname
)

Descending order by last name:

SELECT t1.*
FROM table_name AS t1
WHERE (t1.firstname, t1.lastname) IN(
   SELECT firstname, MAX(lastname)
   FROM table_name
   GROUP BY firstname
)

Ambiguous Entities Scenario

When duplicate name combinations are present, a more complex subquery is required:

SELECT t1.*
FROM table_name AS t1
WHERE t1.id IN(
   SELECT MIN(id)
   FROM table_name
   WHERE (t1.firstname, t1.lastname) IN(
      SELECT firstname, MIN(lastname)
      FROM table_name
      GROUP BY firstname
   )
   GROUP BY firstname, lastname
)

Performance Considerations and Optimization Strategies

In practical applications, query performance is a critical factor. The referenced article case shows that even with DISTINCT queries, execution times can exceed 10 seconds on tables containing 120,000 records.

Key performance optimization strategies include:

For the queue_logs table case, an appropriate indexing strategy includes creating composite indexes for the timestamp, event, and agent_channel columns, which can significantly improve the performance of dependent subqueries.

Best Practice Recommendations

Based on the above analysis, the following best practices are recommended:

  1. In MySQL 5.7.5 and later versions, enable the ONLY_FULL_GROUP_BY SQL mode to ensure query determinism
  2. For scenarios requiring deterministic results, prioritize exclusion join or composite IN subquery methods
  3. In production environments, always test the performance of different methods
  4. Create appropriate index structures for key query columns
  5. Regularly monitor and optimize database configuration parameters

By following these practices, you can ensure both correct results and good query performance when retrieving unique column values with their corresponding data.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.