Search code examples
sqlsqlitegroup-concat

sqlite3 JOIN, GROUP_CONCAT using distinct with custom separator


Given a table of "events" where each event may be associated with zero or more "speakers" and zero or more "terms", those records associated with the events through join tables, I need to produce a table of all events with a column in each row which represents the list of "speaker_names" and "term_names" associated with each event.

However, when I run my query, I have duplication in the speaker_names and term_names values, since the join tables produce a row per association for each of the speakers and terms of the events:

1|Soccer|Bobby|Ball
2|Baseball|Bobby - Bobby - Bobby|Ball - Bat - Helmets
3|Football|Bobby - Jane - Bobby - Jane|Ball - Ball - Helmets - Helmets

The group_concat aggregate function has the ability to use 'distinct', which removes the duplication, though sadly it does not support that alongside the custom separator, which I really need. I am left with these results:

1|Soccer|Bobby|Ball
2|Baseball|Bobby|Ball,Bat,Helmets
3|Football|Bobby,Jane|Ball,Helmets

My question is this: Is there a way I can form the query or change the data structures in order to get my desired results?

Keep in mind this is a sqlite3 query I need, and I cannot add custom C aggregate functions, as this is for an Android deployment.

I have created a gist which makes it easy for you to test a possible solution: https://gist.github.com/4072840


Solution

  • Look up the speaker/term names independently from each other:

    SELECT _id,
           name,
           (SELECT GROUP_CONCAT(name, ';')
            FROM events_speakers
            JOIN speakers
              ON events_speakers.speaker_id = speakers._id
            WHERE events_speakers.event_id = events._id
           ) AS speaker_names,
           (SELECT GROUP_CONCAT(name, ';')
            FROM events_terms
            JOIN terms
              ON events_terms.term_id = terms._id
            WHERE events_terms.event_id = events._id
           ) AS term_names
    FROM events