First tip: count(*) is (depending on your DBMS) frequently slower than count(your_pk_column), so your query will probably be better as
Code:
select count(s.id) as c
from site s
left join health h on s.id = h.site
where h.status = ?
and h.time_of_last_update =
(select max(q.time_of_last_update) from health q where q.site = s.id)
If you want to do that in an SQLQuery, use addScalar("c", Hibernate.INTEGER) where you would have used addEntity in your previous query.
If you want to do that in HQL, the syntax is something like:
Code:
select count(s.id)
from site s
left join s.Health h
where h.Status = :status
and h.lastUpdateTime = (select max(h1.lastUpdateTime) from Health h
where h.Site = s)
If you want to do it using criteria, it's along these lines:
Code:
Criteria crit = session.createCriteria(Site.class, "s");
crit.setProjection(Projections.rowCount());
DetachedCriteria subq = DetachedCriteria.forClass(Health.class, "h");
subq.createAlias("h.Site", "s1");
subq.setProjection(Projections.max("lastUpdateTime"));
subq.add(Property.forName("s1.id").eqProperty("s.id"));
crit.add(Property.forName("lastUpdateTime").eq(subq));
crit.list();
Both the HQL and Criteria versions assume that you have bidriectional associations or collections between Health and Site mappings.
Can you not just do "select count(s.id) from Site s join Health h on s.id = h.site" for this? An inner join should get what you want, seeing as any Site that has one or more equivalent Healths must have an Health with a highest time_of_last_update.
Don't forget to rate the previous post, if it helped.