在SparePart表中,行的唯一性是由materialName和materialNumber的组合给出的,我想要做的是现在获得可用的备件总数。
我尝试过使用count(distinct ...)但它只适用于一个字段而不是两个字段。
带有内部查询的SQL查询(使用hibernate查询语言)如下所示:
select count(*) from (
select distinct materialName, materialNo from SparePart
) as col
答案 0 :(得分:4)
使用子查询+分组,然后筛选代表特定组的第一个ID,最后计算与筛选器匹配的所有ID:
SELECT COUNT(sp2) FROM SparePart sp2 WHERE EXISTS
(SELECT sp.materialName, sp.materialNo
FROM SparePart sp
GROUP BY sp.materialName, sp.materialNo
HAVING MIN(sp.id)=sp2.id)
答案 1 :(得分:1)
您可以使用hibernate方言执行此任务。要做到这一点,创建自己的方言,扩展DB使用的方言(list of all dialects),然后注册新功能。例如,我使用带有InnoDB引擎的MySQL 5:
public final class MyDialect extends MySQL5InnoDBDialect {
public MyDialect() {
super();
registerFunction("pairCountDistinct", new SQLFunctionTemplate(LongType.INSTANCE, "count(distinct ?1, ?2)"));
}
}
然后在persistence.xml中添加新属性:
<property name="hibernate.dialect" value="com.example.dialect.MyDialect" />
现在您可以使用此功能:
// some init actions
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Long> criteria = builder.createQuery(Long.class);
final Root<SparePart> root = criteria.from(SparePart.class);
criteria.select(builder.function("pairCountDistinct", Long.class, root.get(SparePart_.materialName), root.get(SparePart_.materialNo)));
final long result = entityManager.createQuery(criteria).getSingleResult();
// some close actions
答案 2 :(得分:0)
您可以使用Criteria API进行尝试。
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.property("materialName"));
projectionList.add(Projections.property("materialNo"));
Criteria criteria = session.createCriteria(SparePart.class);
criteria.setProjection(Projections.distinct(projectionList);
criteria.setProjection(Projections.rowCount());
Long results = criteria.uniqueResult();
此外,它可能需要一些修改,因为我没有尝试过,根据您的查询进行映射。