【问题标题】:Doing a query for each day in a period, turning it into one query对一段时间内的每一天进行查询,将其变成一个查询
【发布时间】:2011-05-25 21:55:20
【问题描述】:

我有这个:

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,但我不希望需要任何非标准函数。

【问题讨论】:

    标签: java sql database jpa jpql


    【解决方案1】:

    假设您的原始查询是:

    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;
    

    【讨论】:

    • 可以,但是date 函数是从哪里来的呢?是 MySQL 还是标准 JPA/JPQL? Criteria API 中是否有等价物?
    • 我不太确定,但我认为 JPQL 中没有任何明确的日期操作函数(除了获取当前日期/时间)。
    • 根据文档,date() 是一个 MySQL 函数,它从日期或时间戳表达式返回日期。 dev.mysql.com/doc/refman/5.5/en/…
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      您必须使用 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 转换为天数,然后再转换回日期时间,但小时/分钟/秒部分为零。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-31
        • 2023-02-07
        • 1970-01-01
        • 2013-01-18
        • 1970-01-01
        相关资源
        最近更新 更多