Сначала преобразуйте month
и year
в фактические date
. Есть много способов сделать это с вашими данными. Использование concat
для перевода month
и year
в формат, который MySQL распознает как date
, равен единице.
date( concat(year,"-",month,"-",1) ) as created_at;
Это превращает year
и month
в одну дату, начинающуюся с начала месяца.
Затем разделите academic_year
на два столбца с псевдонимами. Мы можем воспользоваться тем, что формат всегда YYYY-YYYY
(вы можете проверить это с помощью where academic_year not rlike '^[0-9]{4}-[0-9]{4}$'
) и использовать left
и right
, чтобы получить первые и последние 4 символа.
left(academic_year, 4), right(academic_year, 4)
Превратите их в даты начала и окончания учебного года.
date( concat(left(academic_year, 4),"-","09","-","01") ) as start_period
date( concat(right(academic_year, 4),"-","08","-","31") ) as end_period
Теперь вы можете работать с created_at
, start_period
и end_period
, используя сравнение between
.
where created_at between start_period and end_period
Соберите все вместе ...
select
date( concat(year,"-",month,"-",1) ) as created_at,
date( concat(left(academic_year, 4),"-","09","-","01") ) as start_period,
date( concat(right(academic_year, 4),"-","08","-","31") ) as end_period
from stuff
where created_at between start_period, end_period;
Обратите внимание, насколько простым становится запрос после того, как вы выполнили работу по преобразованию в надлежащие date
типы. Вместо того, чтобы выполнять специальный анализ для ваших конкретных нужд, лучше нормализовать данные для реальных date
типов и использовать встроенные функции даты MySQL.
Если это вообще возможно, вам следует изменить схему, чтобы она сохранялась непосредственно как date
типы. Это не только упростит задачу, но и ускорит процесс, поскольку столбцы даты могут быть проиндексированы для быстрого поиска. Даже если вы не можете этого сделать, хорошо видеть, как должны храниться такие данные.
Оставьте старые столбцы на месте для обратной совместимости, если необходимо, просто добавьте новые.
add column stuff created_at date not null;
add column stuff academic_year_start date not null;
add column stuff academic_year_end date not null;
Заполните новые столбцы.
update stuff
set created_at = date( concat(year,"-",month,"-",1) ),
academic_year_start = date( concat(left(academic_year, 4),"-","09","-","01") ),
academic_year_end = date( concat(right(academic_year, 4),"-","08","-","31") ) as end_period
И поставить на них указатели.
create index stuff_created_at on stuff (created_at);
create index academic_year on stuff (academic_year_start, academic_year_end);
И как только ваш запрос и все, что угодно, становится очень простым и очень быстрым.
select *
from stuff
where created_at between academic_year_start and academic_year_end;
Поскольку информация об учебном году будет дублироваться много раз, второй редизайн будет состоять в том, чтобы перенести информацию об учебном году в свою собственную таблицу и сослаться на нее как на внешний ключ.