在查询中正确使用HAVING子句

时间:2016-08-31 19:50:28

标签: mysql

我有一个如下所示的查询

SELECT a.day, a.user_id, DATEDIFF(CURDATE(), MAX(b.days_since_login)) as days_since_login 
  FROM stats a, users b
  WHERE a.user_id = b.user_id
  AND a.active = 1
 GROUP BY 
  a.user_id
 HAVING 
  a.day = days_since_login 

我遇到的问题是,如果stats表有多个用户记录,则返回零行。如果只有一行,它将返回它。

我认为我在这里使用HAVING是不正确的。查询计划程序似乎只根据WHERE子句的结果集进行过滤。理想情况下,我有这个非法查询:

SELECT a.day, a.user_id, DATEDIFF(CURDATE(), MAX(b.days_since_login)) as days_since_login 
  FROM stats a, users b
  WHERE a.user_id = b.user_id
  AND a.active = 1
  AND a.day = days_since_login
 GROUP BY 
  a.user_id

但那是不可能的。

1 个答案:

答案 0 :(得分:1)

问题在于,当您使用GROUP BY时,分组列外的任何列都将从组中不可预测的行中获取。它不会在组中搜索与HAVING子句匹配的行,因为该过滤在分组后完成。

您需要加入执行分组的子查询。

SELECT a.day, a.user_id, b.days_since_login
FROM stats AS a
JOIN (SELECT user_id, DATEDIFF(CURDATE(), MAX(b.days_since_login)) as days_since_login 
      FROM users 
      GROUP BY user_id) AS b
ON a.user_id = b.user_id AND a.day = b.days_since_login
WHERE a.active = 1