I have been using QGIS 3.28.0 and want to be able to concatenate the attribute values from differing features into the same label with each concatenated value on a separate line. I would group the aggregate calculation by one of the attributes. My proposed attribute table would look something like the following:


The aim would be to have a single label for the 3 features (these have the same coordinates) like below:


(The concatenation will be grouped by Column A)

To achieve this I tried using the following expression for the label value:

"Column A" ||  '\n' || concatenate ( to_string("Column B") || 'some text' ||  to_string("Column C") || 'some text' ||  '\n' , " Column A")

The expression nearly worked but has given me a trailing blank line. Does anyone have any suggestions for getting rid of this blank line or can anyone offer a better expression to achieve my aims. Any additional advice on how to further sort this label by the numerical values in Column B would also be great.

1 Answer 1


Use the following expression. The basis for the solution is the array_agg() function (line 7), where you concatenate the attribute fields and the texts you want (first argument). Add a second argument group_by and group by Column A. That's it, basically.

The rest of the expression is to create the correct formatting, see below for explanations:

when array_agg ($id, group_by:="Column A")[0] = $id
replace (
    "Column A"  ||  '\n'   ||
    array_to_string (
        array_agg ("Column B"  || ' sometext '  || "Column C"  || ' sometext'  , group_by:="Column A")

enter image description here

Apart from line 7 of the above expression, the rest is to create the correct format:

  • Create only one label per group of common values in Column A using a case ... when condition with the expression on line 2
  • Convert the array to a string (line 6)
  • add the value of Column A followed by a linebreak at the beginning (line 2)
  • Replace the commas (originating from the array) to linebreaks (lines 4 and 9-10)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.