104

有没有办法在 HQL 中创建 Distinct 查询。通过使用“distinct”关键字或其他方法。我不确定 distinct 是否是 HQL 的有效关键字,但我正在寻找 SQL 关键字“distinct”的 HQL 等效项。

4

11 回答 11

130

这是我们使用的 hql 片段。(名称已更改以保护身份)

String queryString = "select distinct f from Foo f inner join foo.bars as b" +
                " where f.creationDate >= ? and f.creationDate < ? and b.bar = ?";
        return getHibernateTemplate().find(queryString, new Object[] {startDate, endDate, bar});
于 2008-11-04T23:25:10.730 回答
60

值得注意的是,distinctHQL 中的关键字并不直接映射到distinctSQL 中的关键字。

如果你distinct在 HQL 中使用关键字,那么 Hibernate 有时会使用distinctSQL 关键字,但在某些情况下它会使用结果转换器来产生不同的结果。例如,当您使用这样的外部联接时:

select distinct o from Order o left join fetch o.lineItems

在这种情况下,无法在 SQL 级别过滤掉重复项,因此 Hibernate在执行 SQL 查询ResultTransformer使用 a来过滤重复项。

于 2008-11-23T22:38:11.247 回答
16

下次做这样的事情

 Criteria crit = (Criteria) session.
                  createCriteria(SomeClass.class).
                  setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

 List claz = crit.list();
于 2011-05-19T23:10:27.423 回答
9

您也可以Criteria.DISTINCT_ROOT_ENTITY与 Hibernate HQL 查询一起使用。

例子:

Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();
于 2014-08-14T14:11:04.663 回答
4

我在结果转换器与 HQL 查询相结合时遇到了一些问题。当我尝试

final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);

它没有用。我不得不像这样手动转换:

final List found = trans.transformList(qry.list());

使用 Criteria API 转换器工作得很好。

于 2009-05-28T10:52:20.393 回答
3

我的主要查询在模型中如下所示:

@NamedQuery(name = "getAllCentralFinancialAgencyAccountCd", 
    query = "select distinct i from CentralFinancialAgencyAccountCd i")

而且我仍然没有得到我认为“不同”的结果。它们只是基于表上的主键组合而不同。

所以在DaoImpl我添加了一行更改并最终获得了我想要的“不同”回报。一个例子是,我现在只看到一次,而不是四次看到 00。这是我添加到的代码DaoImpl

@SuppressWarnings("unchecked")
public List<CacheModelBase> getAllCodes() {

    Session session = (Session) entityManager.getDelegate();
    org.hibernate.Query q = session.getNamedQuery("getAllCentralFinancialAgencyAccountCd");
    q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // This is the one line I had to add to make it do a more distinct query.
    List<CacheModelBase> codes;
    codes = q.list();
    return codes;       
}

我希望这有帮助!再一次,这可能仅在您遵循实现项目的服务、dao 和模型类型的编码实践时才有效。

于 2014-11-03T18:25:09.507 回答
2

假设您有一个映射到 CUSTOMER_INFORMATION 表的客户实体,并且您想要获取客户的不同名字的列表。您可以使用下面的代码段来获得相同的效果。

Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();

我希望它有所帮助。所以在这里我们使用 group by 而不是使用 distinct 关键字。

同样,以前我发现当我想将它应用于多个列时,很难使用 distinct 关键字。例如,我想要获取不同名字、姓氏的列表,然后按分组就可以了。在这种情况下,我很难使用 distinct 。

于 2015-05-12T14:53:28.390 回答
2

您可以像这样在标准构建器中使用不同的关键字。

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Orders> query = builder.createQuery(Orders.class);
Root<Orders> root = query.from(Orders.class);
query.distinct(true).multiselect(root.get("cust_email").as(String.class));

并在您的模型类中创建字段构造函数。

于 2018-08-21T09:31:44.293 回答
1

我得到了 Hibernate Query Language to use Distinct fields 的答案。您可以使用 *SELECT DISTINCT(TO_CITY) FROM FLIGHT_ROUTE*。如果使用SQL查询,则返回字符串列表。您不能通过实体类使用它返回值。因此,解决此类问题的答案是将HQLSQL结合使用。

FROM FLIGHT_ROUTE F WHERE F.ROUTE_ID IN (SELECT SF.ROUTE_ID FROM FLIGHT_ROUTE SF GROUP BY SF.TO_CITY);

SQL查询语句中得到 DISTINCT ROUTE_ID 并作为列表输入。并且 IN 查询从 IN (List) 中过滤出不同的 TO_CITY。

返回类型是实体 Bean 类型。因此,您可以在 AJAX 中使用它,例如AutoComplement

愿一切安好

于 2013-02-22T13:22:17.887 回答
0

如果您需要在 select 语句中为自定义 DTO 使用new关键字并且需要不同的元素,请在 new 之外使用 new ,如下所示 -

select distinct new com.org.AssetDTO(a.id, a.address, a.status) from Asset as a where ...
于 2020-05-11T04:20:01.790 回答
0

您可以简单地添加 GROUP BY 而不是 Distinct

@Query(value = "from someTableEntity where entityCode in :entityCode" +
            " group by entityCode, entityName, entityType")
List<someTableEntity > findNameByCode(@Param("entityCode") List<String> entityCode);
于 2020-05-27T12:04:35.857 回答