3 回答
TA贡献1828条经验 获得超13个赞
首先,使用聚合查询获取产品+购买者组合的最后购买日期。
使用该查询作为匹配元组的子选择:
from Puchases p
where (p.PRODUCT_NAME, p1.PURCHASER_NAME, p1.PURCHASE_DATE) in
(select PRODUCT_NAME, PURCHASER_NAME , max(PURCHASE_DATE)
from Purchases
where
PRODUCT_NAME in :productNames and
PURCHASER_NAME in :purchaserNames
group by PRODUCT_NAME, PURCHASER_NAME)
也应该可以使用标准 API 来实现相同的功能,使用 Subqueries.propertiesIn。
如果您的 PURCHASE_ID 保证“按时间顺序递增”,那么您只需在子选择中使用 max(PURCHASE_ID) 即可。
TA贡献1876条经验 获得超5个赞
在我看来,诀窍是看到“给我最新的”相当于“给没有新购买的行”。这转化为这种查询:
-- This is SQL
-- Note that if two purchases have exactly the same date, this query will
-- return both; you can fine tune the condition inside the exists clause
-- to avoid this
select *
from purchases p1
where
p1.product_name in ('Notebook', 'Pencil') and
p1.purchaser_name in ('Bob', 'Steve') and
not exists (
select p2.purchase_id
from purchases p2
where
p2.product_name = p1.product_name and
p2.purchaser_name = p1.purchaser_name and
p2.purchase_date > p1.purchase_date
)
order by purchase_id;
尽管这是 SQL,但转换为 HQL 应该非常简单,这对您来说可能就足够了。自从我使用 Hibernate Criteria 已经很长时间了(这些天你倾向于使用 JPA API),但它应该是类似的东西:
DetachedCriteria criteria = DetachedCriteria.forClass(Purchase.class, "p1");
// add here your filters to criteria
// criteria.add(purcharserName in (....));
// criteria.add(productName in (....));
// this appends the not exists clause
DetachedCriteria notExistsCriteria = DetachedCriteria.forClass(Purchase.class, "p2");
notExistsCriteria.add(Restrictions.eqProperty("p2.productName", "p1.productName"));
notExistsCriteria.add(Restrictions.eqProperty("p2.purchaserName", "p1.purchaserName"));
notExistsCriteria.add(Restrictions.gtProperty("p2.purchaseDate", "p1.purchaseDate"));
criteria.add(Subqueries.notExists(notExistsCriteria.setProjection(Projections.property("p1.id"))));
List<Purchase> results = // issue Criteria query
更新:
我看到 Hibernate Criteria 支持SQLALL运算符,所以如果你的数据库支持它,你也可以这样写:
DetachedCriteria criteria = DetachedCriteria.forClass(Purchase.class, "p1");
// add here your filters to criteria
// criteria.add(purcharserName in (....));
// criteria.add(productName in (....));
// this appends the p1.purchaseDate > all (...) filter
DetachedCriteria allCriteria = DetachedCriteria.forClass(Purchase.class, "p2");
allCriteria.add(Restrictions.eqProperty("p2.productName", "p1.productName"));
allCriteria.add(Restrictions.eqProperty("p2.purchaserName", "p1.purchaserName"));
criteria.add(Subqueries.propertyGeAll("p1.purchaseDate", allCriteria.setProjection(Projections.property("p2.purchaseDate"))));
List<Purchase> results = // issue Criteria query
读起来更清楚一点。
添加回答
举报