3

在 SparePart 表中,行的唯一性由 materialName 和 materialNumber 的组合给出,我想要做的是获取现在可用的 Spare Parts 总数。

我尝试过使用 count(distinct ...) 但它只适用于一个字段而不是两个字段。

带有内部查询的 SQL 查询(使用休眠查询语言)如下所示:

select count(*) from (
     select distinct materialName, materialNo from SparePart
) as col
4

3 回答 3

4

使用 subquery+group by 然后过滤代表特定组的第一个 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)
于 2012-06-15T12:43:18.313 回答
1

您可以使用休眠方言来完成此任务。为此,请创建自己的方言,扩展 DB 使用的方言(所有方言列表),然后注册新功能。例如,我使用带有 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
于 2015-07-21T08:11:37.837 回答
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();

此外,它可能需要一些修改,因为我没有尝试过,根据您的查询进行映射。

于 2012-06-15T13:18:23.270 回答