简体   繁体   中英

JPQL using MAX and JOIN

I'm trying to get a JPQL query working but can't seem to get it right.

I have 2 entity classes, Product and Pack. A product can have several packs (maybe none), each of which has an expiry date. I'm trying to write a query that returns the product id, pack id and expiry date, but only for the pack that expired most recently, and only if that expiry date is between two values.

Simplified code below:

@Entity
public class Product {
  @Id
  long id;

  @OneToMany(fetch=FetchType.EAGER, mappedBy="product", cascade={CascadeType.ALL})
  Set<Pack> packs;
}

public class Pack {
  @Id
  long id;

  @ManyToOne(fetch=FetchType.LAZY)
  @JoinColumn(name="product_id", nullable=false)
  Product product;

  @Temporal(TemporalType.DATE)
  Date expiryDate;
}

My JPQL is as follows:

"select pk.product.id, pk.id, MAX(pk.expiryDate) as maxExpiry from " + Pack.class.getName() + " pk left join pk.product pr group by pp.id"

I think this works OK, but adding in the second restriction fails with 'incorrect use of group by' errors in mysql if I do this:

"select pk.product.id, pk.id, MAX(pk.expiryDate) as maxExpiry from " + Pack.class.getName() + " pk left join pk.product pr where MAX(pk.expiryDate) between :start and :end group by pp.id"

Can anyone help me get both these restrictions into a single query? Thanks.

How about:

SELECT pk.product.id, pk.id, pk.expiryDate
FROM Pack pk
WHERE pk.expiryDate = (SELECT MAX(ppk.expiryDate) FROM Pack ppk where ppk.product = pk.product) AND
      pk.expiryDate BETWEEN :start AND :end

Please note that if there were more than one pack with maximal expiry date, then this query will return more that one product and set of packs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM