Следующее немного уродливо, но оно учитывает все дни рождения, которые происходят в промежуток времени между start_date и end_date . Если промежуток времени больше года, то он в основном возвращает всех, потому что у всех есть день рождения где-то в этом промежутке времени. Если он меньше года, но начало и конец находятся в разные годы , он использует два между пунктами для определения времени начала и конца года и начала года и времени окончания. Этот запрос также предполагает, что start_date <= end_date </strong>.
Пока у вас есть индекс для DAYOFYEAR (день рождения) , этот запрос выполняется несмотря на его внешний вид.
SET @start_date = '2011-12-01';
SET @end_date = '2012-01-01';
SELECT * FROM users
WHERE DAYOFYEAR( birthday )
BETWEEN IF( YEAR( @end_date ) - YEAR( @start_date ) > 1, 1,
IF( YEAR( @end_date ) - YEAR( @start_date ) > 0,
IF( DAYOFYEAR( @start_date ) <= DAYOFYEAR( @end_date ), 1,
DAYOFYEAR( @start_date ) ),
DAYOFYEAR( @start_date ) ) )
AND IF( YEAR( @end_date ) - YEAR( @start_date ) > 1, 366,
IF( YEAR( @end_date ) - YEAR( @start_date ) > 0, 366,
DAYOFYEAR( @end_date ) ) )
OR DAYOFYEAR( birthday )
BETWEEN IF( YEAR( @end_date ) - YEAR( @start_date ) > 1, 1,
IF( YEAR( @end_date ) - YEAR( @start_date ) > 0, 1,
DAYOFYEAR( @start_date ) ) )
AND IF( YEAR( @end_date ) - YEAR( @start_date ) > 1, 366,
IF( YEAR( @end_date ) - YEAR( @start_date ) > 0,
IF( DAYOFYEAR( @start_date ) <= DAYOFYEAR( @end_date ), 366,
DAYOFYEAR( @end_date ) ),
DAYOFYEAR( @end_date ) ) );