Максим уже отвечает на вопрос, но удалил ответ.
MySQL расширяет предложение HAVING
, поэтому оно работает даже в запросах без агрегации. Это позволяет ему фильтровать запрос, используя псевдонимы - и это может быть удобно. Итак:
SELECT m.id,
FLOOR(DATEDIFF('2019-10-25', c.dob) / 365.25) as age
FROM members m JOIN
crew_cv c
ON m.id = c.user_id
WHERE m.active = 1
HAVING age > 20 AND age < 30
ORDER BY c.last_name, c.first_name
LIMIT 0, 30;
MySQL делает это, потому что имеет тенденцию материализовать подзапросы. Это добавляет накладные расходы для чтения и записи данных. В большинстве других баз данных вы бы просто выразили это, используя подзапрос или CTE, не влияя на производительность. MySQL перегружает HAVING
в качестве альтернативного метода.
И все это говорит о том, что / 365.25
является приближенным. Более точный запрос будет:
SELECT m.id,
FLOOR(DATEDIFF('2019-10-25', c.dob) / 365.25) as age
FROM members m JOIN
crew_cv c
ON m.id = c.user_id
WHERE m.active = 1 AND
c.dob >= DATE('2019-10-25') - INTERVAL 30 YEAR AND
c.dob <= DATE('2019-10-25') - INTERVAL 21 YEAR
ORDER BY c.last_name, c.first_name
LIMIT 0, 30;
Это также имеет то преимущество, что он может использовать индекс для (dob)
, если MySQL считает, что это уместно.