grails-ormgrails-2.0hibernate-criteriadetachedcriteria

Grails Detached Criteria Query and "group by" and "having" clause


In a Grails 2.1 application, I'm having trouble getting a criteria query to behave like some handwritten sql I've got.

So-here's some background info:

The table is in a reporting db and has the following ddl:

completed_case table columns

A row is added to this table whenever a value for that case changes, so there are often >1 rows per caseId.

I've been tasked with finding the first row for each case within a completedDate range. I've got some hacky sql that seems to get me the values I want:

select * from dbo.completed_case where id in 
  (select min(id) 
    from dbo.completed_case cci
    group by case_id
    having ((min(completed_date) > convert(datetime, 'Oct 19 2012 11:01AM', 100)) and  
            (min(completed_date) < convert(datetime, 'Oct 21 2012 11:01AM', 100)))) and 
  status = 'DIAGNOSED'

But I'm not sure how to translate this query into a Grails/Gorm CriteriaQuery. I was guessing the following(using a detached criteria to do the sub select), but it seems like DetachedCriteria doesn't have groupPropery() so I'm a bit lost.

Anyways, here's my guess that includes the not-valid call to groupProperty:

HibernateCriteriaBuilder criteria = CompletedCase.reports.createCriteria()
def results = criteria {

    eqAll("id", new DetachedCriteria(CompletedCase).build {
        projections {
            min("id")
        }
        groupProperty("caseId")   //XXX this method doesn't exist on DetachedCriteria
        between("completedDate", startDate.toDate(), endDate.toDate())
    })
    eq("status", "DIAGNOSED")
    fetchMode 'AssociatedTable', FetchMode.JOIN

}

Is there some way to generate this query using the interfaces provided by Gorm/Grails?

thanks


Solution

  • I just did it using hql.

    select cci from CompletedCase as cci where id in (
                select min(id) from CompletedCase group by caseId
            ) and cci.completedDate > :startDate and cci.completedDate < :endDate and cci.status = :status
            order by cci.id