Hibernate条件查询,子查询连接两列

cha*_*cha 13 hibernate criteria detachedcriteria

我有一个表,"Quote",映射在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
Run Code Online (Sandbox Code Playgroud)

在hibernate中,我认为可以像这样为"group by"子查询创建一个DetachedCriteria(其中Quote是映射表的类,而"Qid"是键的复合id类,具有属性id和date,由a访问Quote类的"qid"属性):

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

但是,我不确定如何在标准查询中使用它,该查询等同于上面的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();
Run Code Online (Sandbox Code Playgroud)

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

小智 12

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

SELECT *
FROM Quote q1
INNER JOIN (
    SELECT id, MAX(date) AS maxdate
    FROM Quote
    GROUP BY id
) q2
    ON q1.id = q2.id AND q1.date = q2.maxdate;
Run Code Online (Sandbox Code Playgroud)

尝试:

SELECT *
FROM Quote q1
WHERE q1.date = (SELECT MAX(date) FROM Quote inner where inner.id = q1.id)
Run Code Online (Sandbox Code Playgroud)

关键的区别在于,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 ));
Run Code Online (Sandbox Code Playgroud)

生成的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
        );
Run Code Online (Sandbox Code Playgroud)

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

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