对一段时间内的每一天进行查询,将其转换为一个查询

时间:2010-12-15 13:10:24

标签: java sql database jpa jpql

我有这个:

public Map<Day,Integer> getUniqueLogins(long fromTime, long toTime) {

  EntityManager em = emf.createEntityManager();
  try {
   Map<Day,Integer> resultMap = new ...;
   for (Day day : daysInPeriod(fromTime, toTime)) {

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Long> q = cb.createQuery(Long.class);

    // FROM UserSession
    Root<UserSession> userSess = q.from(UserSession.class);
    // SELECT COUNT(DISTINCT userId)
    q.select(cb.countDistinct(userSess.<Long>get("userId")));
    // WHERE loginTime BETWEEN ...
    q.where(cb.between(userSess.<Date>get("loginTime"), day.startDate(), day.endDate()));

    long result = em.createQuery(q).getSingleResult();
    resultMap.put(day, (int) result);
   }
   return resultMap;
  } finally {
   em.close();
  }

 }

这会对给定时间段内的每一天执行查询(该时间段为一个月的数量级)。

我可以在一个查询中获取此特定数据吗?我正在使用Hibernate / MySQL,但我不想要任何非标准功能。

3 个答案:

答案 0 :(得分:2)

假设您的原始查询是:

SELECT COUNT(DISTINCT userId)
FROM UserSession
WHERE loginTime BETWEEN dayStart AND dayEnd;

这应该返回与每个期间每天运行原始结果相同的结果:

SELECT date(loginTime) AS day, COUNT(DISTINCT userId)
FROM UserSession
WHERE loginTime BETWEEN startDate AND endDate
GROUP BY day;

答案 1 :(得分:1)

GROUP BY计算不同用户ID的LoginTime的日期段。后端应提供一种方法来提取日期时间值的日期部分。

答案 2 :(得分:1)

您必须使用MySQL特定功能才能执行此操作。

SELECT FROM_DAYS(TO_DAYS(loginTime)) AS day, COUNT(DISTINCT userId)
FROM UserSession
WHERE loginTime BETWEEN :fromTime AND :toTime
GROUP BY day

from_days / to_days会将loginTime转换为天数,然后返回日期时间,但小时/分钟/秒部分为零。