使用子查询连接两列的Hibernate条件查询

我有一张表,“引用”,映射在hibernate中,它具有一个整数id和一个日期的复合键,以及几个额外的列。 我想编写一个使用DetachedCriteria的条件查询来获取每个具有最大日期的id的行。

在SQL中,我可能会写一个类似的查询

SELECT * FROM Quote q1
  INNER JOIN (SELECT id, max(date) as maxdate FROM Quote
               GROUP BY id, date) q2
  ON q1.id = q2.id AND q1.date = q2.maxdate

在hibernate中,我认为可以像这样为“group by”子查询创建一个DetachedCriteria(其中Quote是映射表的类,而“Qid”是key的复合id类,属性id和日期,由引用类的“qid”属性):

DetachedCriteria maxDateQry = DetachedCriteria.forClass(Quote.class);
maxDateQry.setProjection(
    Projections.projectionList()
        .add(Projections.max("qid.date", "maxdate"))
        .add(Projections.groupProperty("qid.id")));

但是,我不确定如何在标准查询中使用它,该标准查询将等同于上面的sql的外部部分。 我正在寻找一些沿线的东西

Criteria criteria = session.createCriteria(Quote.class);
criteria.add(
    Restrictions.and(
        Property.forName("qid.id").eq(maxDateQry???),
        Property.forName("qid.date").eq(maxDateQry???)));
List<Quote> quoteList = criteria.list();

上面的两个Property.forName将外部表与子查询的相应列相关联。 如果内部联接只提供一个值,我只需给DetachedCriteria一个Projection,然后直接将DetachedCriteria传递给Property.forName(...)。eq(..)。 我不知道如何在Projection中使用带有两个值(id和maxdate)的DetachedCriteria。


有完全相同的问题,并找不到多列子查询匹配的确切解决方案。 我所做的是重写查询,以便它只需要匹配ONE列中的子查询。 所以,而不是

SELECT * FROM Quote q1
  INNER JOIN (SELECT id, max(date) as maxdate FROM Quote
               GROUP BY id, date) q2
  ON q1.id = q2.id AND q1.date = q2.maxdate

尝试

SELECT * FROM Quote q1 where g1.date = 
       (SELECT max(inner.date) FROM Quote inner where inner.id = g1.id
                   GROUP BY inner.id)

关键区别在于,所有条形图JOIN标准的MAX条件现在都在内部SELECT内。

标准/分离标准如下所示:

DetachedCriteria innerCriteria = DetachedCriteria.forClass(Quote.class, "inner")
    .add(Restrictions.eqProperty("inner.id","q1.id"))
    .setProjection(Projections.projectionList().add(Projections.max("inner.date")));

DetachedCriteria outerCriteria= DetachedCriteria.forClass(ClmClaim.class, "q1");
outerCriteria.add(Subqueries.propertyEq("q1.date", innerCriteria ));

生成的SQL如下所示:

select
        this_.<Blah> as blah2_49_0_,
        this_.<Blah> as blah2_50_0_,
        this_.<Blah> as blah2_51_0_,

    from
        Quote this_ 
    where
         this_.date = (
            select
                max(inner_.date) as y0_ 
            from
                Quote inner_ 
            where
                inner_.claim_number=this_.claim_number
        );

您会注意到SQL中没有'group by',因为它不是必需的。 如果在子选择中有多个匹配条件,我会希望有人在那里。

无论如何,希望它有帮助。 这是圣诞节前我要做的最后一件事!


我有一个类似的用例。 我很确定它不能用Criteria完成。 Hibernate不支持from子句中的连接:https://hibernate.atlassian.net/browse/HHH-3356(在撰写本文时仍然打开)。

2013年圣诞节的回答非常好,但不幸的是,相关的子查询在我的使用情况中非常糟糕:

  • 使用MySQL
  • 每个ID可以有数千个日期
  • 但是这个很好(对于MySQL 5.6.25而言):

    SELECT * FROM Quote q1
    WHERE (q1.id, q1.date) IN 
    (
        SELECT id, max(date)
        FROM Quote
        GROUP BY id, date
    )
    

    我来到这里寻找答案

    DetachedCriteria maxDateQry = DetachedCriteria.forClass(Quote.class);
    maxDateQry.setProjection(
        Projections.projectionList()
            .add(Projections.groupProperty("qid.id"))
            .add(Projections.max("qid.date", "maxdate"))
        );
    
    Criteria criteria = session.createCriteria(Quote.class);
    Object environmentIdAndStartedDateProperty = "(environmentId, startedDate)" // but not this, some sort of magic
    criteria.add(
        Subqueries.in(environmentIdAndStartedDateProperty, maxDateQry));
    List<Quote> quoteList = criteria.list();
    

    但看起来没有这样的魔法存在。 我不得不放弃并使用hql ,这可能是最好的,因为根据Hibernate 4.2文档,hibernate标准API已被弃用:https://docs.jboss.org/hibernate/orm/4.2/devguide/en-美国/ HTML / apb.html

    链接地址: http://www.djcxy.com/p/37057.html

    上一篇: Hibernate criteria query with subquery joining two columns

    下一篇: JPA native query result returns duplicate child objects