Having
We can add expressions to the having clause when we use Dynamic formula, @Aggregation properties or RawSql.
Dynamic formula
See here for more details on dynamic aggregation formula (sum, min, max, count, avg).
// e.g. sum(hours)
List<DMachineStats> result =
new QDMachineStats()
.select("date, sum(totalKms), sum(hours)")
.havingClause()
.gt("sum(hours)", 2) // (1) having clause
.findList();
select t0.date, sum(t0.total_kms), sum(t0.hours)
from d_machine_stats t0
group by t0.date
having sum(t0.hours) > ? -- (1) having clause
@Aggration
With @Aggration and @Sum properties these are properties on the query bean
so we just use them as normal but after having()
.
Example:
@Entity
@Table(name = "orders")
public class Order extends BaseModel {
...
LocalDate orderDate;
@Aggregation("max(orderDate)") // aggregation property
LocalDate maxOrderDate;
@Aggregation("count(*)") // aggregation property
Long totalCount;
So we can use maxOrderDate and totalCount properties like other query bean properties. Add predicates on these aggregation properties to the having clause like:
List<Order> orders = new QOrder()
.select(o.status, o.maxOrderDate, o.totalCount)
.status.notEqualTo(Order.Status.COMPLETE) // (1) where clause - non aggregate properties
.having()
.totalCount.greaterThan(1) // (2) having clause - aggregate properties
.findList();
select t0.status, max(t0.order_date), count(*)
from orders t0
where t0.status <> ? // (1)
group by t0.status
having count(*) > ? // (2)
RawSql
With parsed RawSql we can also add expressions to the having clause.
Example
String sql =
"select order_id, count(*) as totalItems, sum(order_qty*unit_price) as totalAmount \n" +
"from o_order_detail \n" +
"group by order_id";
RawSql rawSql = RawSqlBuilder.parse(sql).columnMapping("order_id", "order.id").create();
List<OrderAggregate> l2 = DB.find(OrderAggregate.class)
.setRawSql(rawSql)
.where()
.gt("order.id", 0)
.having() // having clause
.lt("totalItems", 3)
.gt("totalAmount", 50)
.findList();