2010-12-15 79 views
3

我有这样的:做好每一天的时间段查询,把它变成一个查询

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,但我不想要任何非标准功能。

回答

1

GROUP BY由LoginTime的日期段统计不同的userids。后端应该提供一种方法来提取日期时间值的日期部分。

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; 
+0

这会工作,但那个'日期'功能从哪里来?是MySQL还是标准JPA/JPQL? Criteria API中是否有等价物? – 2010-12-15 14:27:50

+0

我不太确定,但我不认为JPQL中有任何明确的日期操作函数(除了获取当前的日期/时间)。 – 2010-12-15 14:36:51

+0

根据文档,date()是一个MySQL函数,它返回日期或时间戳表达式的日期。 http://dev.mysql.com/doc/refman/5.5/zh-CN/date-and-time-functions.html#function_date – 2011-01-11 02:45:08

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转换为天数,然后返回日期时间,但与时/分/秒部分zero'd。

相关问题