有人可以解释一下我如何改进这样的查询,以便它尽可能快地运行并且它也更清洁?正如你所看到的,我有两个完全相同的选择,但我需要能够计算出这一切的数量,所以我不确定改变这样的最佳方法是什么:
SELECT COUNT(*) AS count FROM users
WHERE users.activated = '1'
AND (SELECT TIMESTAMPDIFF(YEAR, birthdate, CURDATE()) FROM users AS users2 WHERE users2.id = users.id) >= '18'
AND (SELECT TIMESTAMPDIFF(YEAR, birthdate, CURDATE()) FROM users AS users2 WHERE users2.id = users.id) <= '28'
基本上我需要得到18到28岁之间所有用户的数量。 users.birthdate
是日期列。
有人可以帮忙吗?我怎样才能使用select
子句中的2 where
只作为一个,所以它不会执行相同的2次?
编辑:
另一个例子,我也有这个查询,我需要在where子句中多次使用:
SELECT COUNT(*) AS count FROM users
WHERE ROUND((DEGREES(ACOS(SIN(RADIANS('$c_lat')) * SIN(RADIANS(users.lat)) + COS(RADIANS('$c_lat')) * COS(RADIANS(users.lat)) * COS(RADIANS('$c_lng' - users.lng))))) * 60 * 1.1515 * 1.60934 * 1000) >= 1000
AND ROUND((DEGREES(ACOS(SIN(RADIANS('$c_lat')) * SIN(RADIANS(users.lat)) + COS(RADIANS('$c_lat')) * COS(RADIANS(users.lat)) * COS(RADIANS('$c_lng' - users.lng))))) * 60 * 1.1515 * 1.60934 * 1000) <= 5000
这个用户可以获得距离我们通过的$ c_lat和$ c_lng 1000米到5000米之间的所有用户。
试着了解什么是解决MySQL中这类问题的最佳方法。
谢谢!
答案 0 :(得分:4)
我认为没有理由为此使用子查询。编写查询的更好方法是:
SELECT COUNT(*) AS count
FROM users u
WHERE u.activated = '1' AND
u.birthdate <= date_sub(CURDATE(), interval 18 years) AND
u.birthdate >= date_sub(CURDATE(), interval 28 years);
如上所述,此查询可以利用users(activated, birthdate)
上的索引。特别是,第二个条件可能更好地写为:u.birthdate > date_sub(CURDATE(), interval 29 years)
。
注意:日期算术的确切逻辑可能有点偏差。目前尚不清楚你的意思是在18到28岁之间&#34;
答案 1 :(得分:0)
对于第二个例子,你可以试试这个:
$_POST
您通常使用&#39; WHERE&#39;中的计算或比较。条款区域,尝试使用&#39; HAVING&#39;然后根据列的预期处理结果设置过滤器。类似的东西:
SELECT
COUNT(*) AS count,
ROUND((DEGREES(ACOS(SIN(RADIANS('$c_lat')) * SIN(RADIANS(users.lat)) + COS(RADIANS('$c_lat')) * COS(RADIANS(users.lat)) * COS(RADIANS('$c_lng' - users.lng))))) * 60 * 1.1515 * 1.60934 * 1000) AS var_one,
ROUND((DEGREES(ACOS(SIN(RADIANS('$c_lat')) * SIN(RADIANS(users.lat)) + COS(RADIANS('$c_lat')) * COS(RADIANS(users.lat)) * COS(RADIANS('$c_lng' - users.lng))))) * 60 * 1.1515 * 1.60934 * 1000) AS var_two
FROM
users
HAVING
var_one >= 1000
AND var_two <= 5000;
这将显示交易记录大于10的产品