Преобразование функции TRUNC (дата) из Oracle в MySQL
Функция TRUNC (date) возвращает дату с временной частью дня, усеченной до единицы, указанной в модели формата fmt. MySQL не поддерживает функцию TRUNC, поэтому необходимо создать дополнительный объект, а именно функцию, которая имитирует работу функции TRUNC.
Создадим следующую функцию:
CREATE FUNCTION SWF_TruncDate(pDate datetime, FmtStr varchar(255))
RETURNS DATE
DETERMINISTIC
BEGIN
IF (UPPER(FmtStr) = 'YEAR' or UPPER(FmtStr) = 'YY' or UPPER(FmtStr) = 'YYYY' or UPPER(FmtStr) = 'Y' or UPPER(FmtStr) = 'YYY') THEN
RETURN makedate(year(pDate),1);
ELSEIF (UPPER(FmtStr) = 'MONTH' or UPPER(FmtStr) = 'MM' or UPPER(FmtStr) = 'MON') THEN
RETURN concat(makedate(year(pDate),dayofyear(pDate)-day(pDate)+1));
ELSEIF (UPPER(FmtStr) = 'DD' or UPPER(FmtStr) = 'DDD') THEN
RETURN date(pDate);
ELSEIF (UPPER(FmtStr) = 'HOUR' or UPPER(FmtStr) = 'HH' or UPPER(FmtStr) = 'HH12' or UPPER(FmtStr) = 'HH24') THEN
RETURN date(pDate);
ELSEIF (UPPER(FmtStr) = 'MINUTE' or UPPER(FmtStr) = 'MI') THEN
RETURN date(pDate);
ELSEIF (UPPER(FmtStr) = 'Q') THEN
RETURN MAKEDATE(YEAR(pDate), 1) + INTERVAL QUARTER(pDate) QUARTER - INTERVAL 1 QUARTER;
ELSE
RETURN date(pDate);
END IF;
END;
Функция проверяет параметр FmtStr, и если он имеет значение 'YEAR'/'YY'/'YYY'/'YYY', то она возьмет год, указанный в параметре pDate, и объединит его с '-01-01' (1 января). Если параметр FmtStr имеет значение 'MONTH'/'MM'/'MON', функция вернет конкатенацию года, месяца из параметра pDate и '-01', то есть начало месяца. Если параметр FmtStr имеет значение 'DD'/'DDD'/'D'/'DY'/'DAY', функция вернет дату, усеченную до дня. 'DD' является значением по умолчанию, если параметр FmtStr не указан в источнике. Если параметр FmtStr имеет значение 'HOUR'/'HH'/'HH12'/'HH24', то возвращаемое значение будет представлять собой дату, усеченную до часа. Если параметр FmtStr имеет значение 'MINUTE'/'MI', то возвращаемое значение будет представлять собой дату, усеченную до минуты.
Рассмотрим, как работает эта функция:
| Oracle |
MySQL |
select trunc(TO_DATE('25-AUG-22','DD-MON-YY')) from dual;
TRUNC(TO_DATE('25-AUG-22','DD-MON-YY'))
|
25-AUG-22
|
|
select SWF_TruncDate(STR_TO_DATE('25-AUG-22','%d-%b-%y'),'DD');
SWF_TruncDate(STR_TO_DATE('25-AUG-22','DD-MON-YY'))
|
2022-08-25
|
|
select trunc(TO_DATE('25-AUG-22','DD-MON-YY'), 'YY') from dual;
TRUNC(TO_DATE('25-AUG-22','DD-MON-YY'),'YY')
|
01-JAN-22
|
|
select SWF_TruncDate(STR_TO_DATE('25-AUG-22','%d-%b-%y'),'YY');
SWF_TruncDate(STR_TO_DATE('25-AUG-22','DD-MON-YY'))
|
2022-01-01
|
|
select trunc(TO_DATE('25-AUG-22','DD-MON-YY'), 'MONTH') from dual;
TRUNC(TO_DATE('25-AUG-22','DD-MON-YY'),'MONTH')
|
01-AUG-22
|
|
select SWF_TruncDate(STR_TO_DATE('25-AUG-22','%d-%b-%y'),'MONTH');
SWF_TruncDate(STR_TO_DATE('25-AUG-22','DD-MON-YY'))
|
2022-08-01
|
|
select trunc(TO_DATE('25-AUG-22','DD-MON-YY'), 'DDD') from dual;
TRUNC(TO_DATE('25-AUG-22','DD-MON-YY'),'DDD')
|
25-AUG-22
|
|
select SWF_TruncDate(STR_TO_DATE('25-AUG-22','%d-%b-%y'),'DDD');
SWF_TruncDate(STR_TO_DATE('25-AUG-22','DD-MON-YY'))
|
2022-08-25
|
|
Как видите, функция TRUNC была заменена созданной функцией SWF_TruncDate. После завершения конвертации запросы эквивалентны и возвращают один и тот же набор результатов.