Search code examples
mysqlgroup-concat

MySQL Group Concat of First Few and Last Few Lines


I have a MySQL table with three columns as follows:

    ID  Line    Text
    1001    1   Line 1 Text
    1001    2   Line 2 Text
    1001    3   Line 3 Text
    1001    4   Line 4 Text
    1001    5   Line 5 Text
    1001    6   Line 6 Text
    1002    1   Line 1 Text
    1002    2   Line 2 Text
    1002    3   Line 3 Text
    1002    4   Line 4 Text
    1002    5   Line 5 Text
    1002    6   Line 6 Text     
    1002    7   Line 7 Text

Minimum number of lines could vary for each ID (could be as high as 100) but there are a minimum of 6 lines for each ID.

I would like to do a group_concat of Text by taking only the first 3 lines and the last two lines for each ID as follows:

    ID     Text
    1001    Line 1 Text Line 2 Text Line 3 Text Line 5 Text Line 6 Text
    1002    Line 1 Text Line 2 Text Line 3 Text Line 6 Text Line 7 Text

I use the following code when I want to do group_concat on all lines:

    SELECT ID, GROUP_CONCAT(Text SEPARATOR ' ') AS textConcat
    FROM table
    GROUP BY ID

I could probably put a where condition as follows if I want to extract only the first 3 lines:

    SELECT ID, GROUP_CONCAT(Text SEPARATOR ' ') AS textConcat
    FROM table
    WHERE Line <= 3
    GROUP BY ID

I am not sure how to get the last two lines as well

Could someone please help me with MySQL query for this? Thank you.


Solution

  • You can do this by concatenating the results of two group concats:

    SELECT ID,
           concat(substring_index(GROUP_CONCAT(Text SEPARATOR ' '), ' ', 3),
                  substring_index(GROUP_CONCAT(Text SEPARATOR ' '), ' ', -2)
                 ) as textConcat
    FROM table
    GROUP BY ID;
    

    If the lines are long, they do run the risk of overflowing the default string size for group_concat().

    You can also do this as:

    select t.id, group_concat(t.line separator ' ' order by t.id) as lines
    from table t join
         (select id, max(line) as numlines
          from table t
          group by id
         ) tl
         on t.id = tl.id
    where t.line <= 3 or t.line > t.numlines - 2;