Gravatar Image

Frank Corso

Data Lover | Indie Software Founder | Full-Stack Developer

Need help with any data or Python problem?

I have a few spots open for select freelance projects involving software engineering, data pipelines, visualization, and machine learning. Let's discuss how I might help.

How To Use MySQL’s GROUP_CONCAT To Get Aggregated Lists of Values

Published on

When analyzing data in your MySQL database or querying for data, there are times when you have data points that could have multiple values. For example, a post might have multiple tags, or an order might have multiple products.

Querying for these is fairly straightforward, but sometimes, you want results where a single row in the response includes both the parent data and the children’s data.

There are several ways to do this, but the easiest is using MySQL’s GROUP_CONCAT function. GROUP_CONCAT can take a group of data points and convert them into a single value in a comma-separated list. I tend to use this function at least several times a week.

Example Using GROUP_CONCAT

The most basic way to use this function is just grouping together values from a single table.

Let’s say we have a “Survey” table that contains user research surveys. This table might have a title column for what the user named the survey.

If we wanted to get a comma-separated list of all the names, we could do something like this SQL:

SELECT GROUP_CONCAT(title)
FROM Survey;
Post-sale survey,Random Test Survey,Testing Potential Survey,what does this do?,My Survey

Of course, you wouldn’t normally get all values of a column for the whole database so this would normally contain a WHERE statement like this:

SELECT GROUP_CONCAT(title)
FROM Survey
WHERE user_id = 17;
Post-sale survey,My Survey

This allows us to quickly get a list of values from the table.

We can also adjust the separator if we don’t want to use commas. Using the SEPARATOR keyword will let us change that, as in this SQL:

SELECT GROUP_CONCAT(title SEPARATOR '; ')
FROM Survey
WHERE user_id = 17;
Post-sale survey; My Survey

Using GROUP_CONCAT on a single table is helpful to quickly see a list of values. I use this when I am grouping by specific values within the table for analysis.

While using this within a table is useful, the greater usefulness of GROUP_CONCAT comes when you are getting values from multiple tables.

Example Using GROUP_CONCAT in a Subquery

Let’s say we have our Survey table and a Question table that contains questions within the surveys. The Question table has various columns, but the ones we care about are survey_id, which tells us which survey it belongs to, and title, which is the question itself.

Now, let’s say we wanted to perform a query to get all surveys by a user and include a list of all questions in each survey. We can do this using GROUP_CONCAT in a SELECT subquery.

SELECT title, (
    SELECT GROUP_CONCAT(title)
    FROM Question
    WHERE survey_id = Survey.id
) as questions
FROM Survey
WHERE user_id = 17;
title questions
Post-sale Survey How easy was our checkout process?,What almost stopped you from making this purchase?
My Survey Test Question,Another Fake Question

Example Using GROUP_CONCAT in a Subquery With JOIN

While this works well for a lot of use cases already, you will often have a many-to-many relationship that you want to pull into this query.

Let’s say we have a third and fourth table, Tag and Survey_Tag. These tables create a many-to-many relationship for different tags people can attach to their surveys for filtering and reporting purposes.

We can update our previous query to pull in both the questions and the tags by using a JOIN in the tags subquery. Depending on how large your database is and how well it’s optimized, you might need to be narrower in your queries to avoid timeouts or this taking a long time. However, assuming our database is an average size, this SQL would work:

SELECT title, (
    SELECT GROUP_CONCAT(title)
    FROM Question
    WHERE survey_id = Survey.id
) as questions, (
    SELECT GROUP_CONCAT(title)
    FROM Survey_Tag
    LEFT JOIN Tag ON Survey_Tag.tag_id = Tag.id
    WHERE Survey_Tag.survey_id = Survey.id
) as tags
FROM Survey
WHERE user_id = 17;
title questions tags
Post-sale Survey How easy was our checkout process?,What almost stopped you from making this purchase? checkout,revenue,sales funnel
My Survey Test Question,Another Fake Question random,testing

Once you start using GROUP_CONCAT, you will start seeing uses for it in many of your queries.