2015-04-02 3 views
0

Я столкнулся с странным, неожиданным поведением при использовании функции CURRENT_DATE в MySQL. Рассмотрим следующий пример:странное поведение MySQL при использовании CURRENT_DATE минус числовое значение

SELECT 
    DATE(CURRENT_DATE - 0) AS 'today', 
    DATE(CURRENT_DATE - 1) AS 'yesterday', 
    DATE(CURRENT_DATE - 2) AS '2 days ago', 
    DATE(CURRENT_DATE - 3) AS '3 days ago' 

Как ни странно, это возвращает две даты и два NULL значения (при выполнении на 2015-04-01). Следующий код возвращает четыре даты, как и ожидалось:

SELECT 
    DATE_ADD(CURRENT_DATE, INTERVAL 0 DAY) AS 'today', 
    DATE_ADD(CURRENT_DATE, INTERVAL -1 DAY) AS 'yesterday', 
    DATE_ADD(CURRENT_DATE, INTERVAL -2 DAY) AS '2 days ago', 
    DATE_ADD(CURRENT_DATE, INTERVAL -3 DAY) AS '3 days ago' 

Кто знает, почему прежний набор кода возвращает неожиданные результаты, а последние возвращает ожидаемые результаты?

+0

Итак, почему, по-вашему, вы можете вычитать целые числа с даты? – zerkms

ответ

1

Значения констант даты и даты и времени не являются датами и временем. Они либо строки или числа, так как документация почти объясняет ясно:

Возвращает текущую дату в качестве значения в «YYYY-MM-DD» или ГГГГММДД формате, в зависимости от того, используется ли функция в строке или числовой контекст.

- создает числовой контекст. Таким образом,

DATE(CURRENT_DATE - 0) --> DATE(20150401 - 1) = DATE(20150401) 

Это верно преобразуется. Но учтите:

DATE(CURRENT_DATE - 2) --> DATE(20150401 - 2) = DATE(20150399) 

Недействительная дата. Поэтому он не конвертируется. Кроме того, MySQL распознает 20150400 как дату, поэтому он преобразуется без ошибок.

При использовании MySQL моя рекомендация заключается в использовании date_add() и date_sub() для всех манипуляций с датами, если только столбец даты не напечатан как тип данных даты.

+0

Спасибо, это понятно и полезно. Я проголосую за ответ, но только начинаю свой рассказ ... так увы, я не могу. – mkprkr

1

Поскольку CURRENT_DATE - это дата, а не целое число. Рассмотрим первый запрос. Что вы подразумеваете под -1? -1 секунда? минут? час? день? месяц? год? Как MySQL должен догадываться об этом? Следовательно, существование заявлений INTERVAL

+0

Спасибо за быстрый ответ. Обычно, когда вы вычитаете 1 из CURRENT_DATE, он действительно вычитает один день. Поскольку это поведение по умолчанию, и поскольку я видел это неоднократно, я ожидал его. Обоснование, которое вы предлагаете, объясняет, почему подход DATE_ADD обычно предпочтительнее (поскольку я вынужден указать INTERVAL как ДЕНЬ), но это не объясняет, почему в некоторых случаях CURRENT_DATE - 1 возвращает NULL. Объяснение этого объясняет @ Gordon-Linoff. – mkprkr

Смежные вопросы