使用COUNT的奇怪的MySQL行为

时间:2012-12-24 00:14:54

标签: mysql sql

我对MySQL数据库有这个非常奇怪的问题。

为了简化查询,我们只是说我正在调用此查询以获取与用户设置匹配的配置文件:

SELECT u.*, floor(datediff(now(), u.birth_date) / 365) as age 
FROM users_wr u 
LEFT JOIN cities c ON c.id = u.city_id 
WHERE u.id != 1 and c.country_id = 71
HAVING age >= 20 AND age <= 25

此查询现在返回3行的集合(这是正确的)。但是,当我想获得这样的行数时:

SELECT count(*), floor(datediff(now(), u.birth_date) / 365) as age 
FROM users_wr u 
LEFT JOIN cities c ON c.id = u.city_id 
WHERE u.id != 1 and c.country_id = 71
HAVING age >= 20 AND age <= 25
LIMIT 1

然后在另一种情况下它应该返回4,但它保持返回5,在这种情况下,当它应该返回3时它返回NULL。

我不知道那是什么意思。我不是sql的初学者,这真的很困扰我。

2 个答案:

答案 0 :(得分:1)

您忘记添加GROUP BY子句

SELECT count(*), floor(datediff(now(), u.birth_date) / 365) as age 
FROM users_wr u 
LEFT JOIN cities c ON c.id = u.city_id 
WHERE u.id != 1 and c.country_id = 71
GROUP BY floor(datediff(now(), u.birth_date) / 365)
-- HAVING age >= 20 AND age <= 25
-- LIMIT 1

答案 1 :(得分:0)

您的SQL查询很奇怪,因为您正在使用名为隐藏列的MySQL(错误)功能。在任何其他数据库中,这些查询都是语法违规,因为select中没有group by的聚合函数和非聚合列都有。这是坏习惯。

在第一种情况下,您将获得与条件匹配的调用行,因为没有聚合。

在第二种情况下,即使没有limit,查询也只返回 1 行。您可以获得满足wherehaving条件的总计数和随机年龄。

您想要的查询是:

select count(*)
from (SELECT u.*, floor(datediff(now(), u.birth_date) / 365) as age 
      FROM users_wr u LEFT JOIN
           cities c ON c.id = u.city_id 
      WHERE u.id != 1 and c.country_id = 71
     ) t
where age >= 20 AND age <= 25

这应返回一行,其中包含满足所有条件的用户数。