有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在一段时间内每天执行一个查询,将其转换为一个查询

我有这个:

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) 个答案

  1. # 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会将登录时间转换为若干天,然后再转换回日期时间,但小时/分钟/秒部分为零

  2. # 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;
    
  3. # 3 楼答案

    按LoginTime的日期段对不同的用户ID进行分组。后端应该提供一种方法来提取datetime值的日期部分