diff --git a/querydsl-libraries/querydsl-sql/src/main/java/com/querydsl/sql/SQLExpressions.java b/querydsl-libraries/querydsl-sql/src/main/java/com/querydsl/sql/SQLExpressions.java index 535b077b44..b7d0ddeae4 100644 --- a/querydsl-libraries/querydsl-sql/src/main/java/com/querydsl/sql/SQLExpressions.java +++ b/querydsl-libraries/querydsl-sql/src/main/java/com/querydsl/sql/SQLExpressions.java @@ -18,6 +18,7 @@ import com.querydsl.core.types.Expression; import com.querydsl.core.types.Operator; import com.querydsl.core.types.Ops; +import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.Path; import com.querydsl.core.types.SubQueryExpression; import com.querydsl.core.types.dsl.BooleanExpression; @@ -700,6 +701,20 @@ public static WithinGroup listagg(Expression expr, String delimiter) return new WithinGroup<>(String.class, SQLOps.LISTAGG, expr, ConstantImpl.create(delimiter)); } + /** + * PostgreSQL specific string_agg aggregate function. + * + *

Use {@link WithinGroup#withinGroup()} followed by {@link WithinGroup.OrderBy#orderBy(OrderSpecifier...)} + * to specify the ORDER BY clause.

+ * + * @param expr expression to be aggregated + * @param delimiter delimiter string + * @return string_agg(expr, delimiter) + */ + public static WithinGroup stringAgg(Expression expr, String delimiter) { + return new WithinGroup<>(String.class, SQLOps.GROUP_CONCAT2, expr, ConstantImpl.create(delimiter)); + } + /** * NTH_VALUE returns the expr value of the nth row in the window defined by the analytic clause. * The returned value has the data type of the expr. diff --git a/querydsl-libraries/querydsl-sql/src/test/java/com/querydsl/sql/WithinGroupTest.java b/querydsl-libraries/querydsl-sql/src/test/java/com/querydsl/sql/WithinGroupTest.java index 5dad0d8d75..345b9b4daa 100644 --- a/querydsl-libraries/querydsl-sql/src/test/java/com/querydsl/sql/WithinGroupTest.java +++ b/querydsl-libraries/querydsl-sql/src/test/java/com/querydsl/sql/WithinGroupTest.java @@ -80,4 +80,14 @@ public void listaggCommaWithSpace() { public void listaggIntString() { assertThat(toString(SQLExpressions.listagg(path, "1"))).isEqualTo("listagg(path,'1')"); } + + @Test + public void stringAgg_with_orderBy() { + var expr = + SQLExpressions.stringAgg(path, ", ") + .withinGroup() + .orderBy(path2.asc()) + .getValue(); + assertThat(toString(expr)).isEqualTo("string_agg(path,', ') within group (order by path2 asc)"); + } }