Несовместимое сравнение даты MySQL ГГГГ / ММ / ДД с ГГГГ-ММ-ДД - PullRequest
2 голосов
/ 13 ноября 2008

У меня есть запрос MySQL (v 5, MyISAM), который возвращает разные строки в зависимости от формата строки даты.

(1) IFNULL(date1, ADDDATE('2008/10/31 23:59:59',INTERVAL 1 DAY)) > '2008-10-31 23:59:59'
(2) IFNULL(date1, ADDDATE('2008/10/31 23:59:59',INTERVAL 1 DAY)) > '2008/10/31 23:59:59'

(3) date1 > '2008-10-31 23:59:59'
(4) date1 > '2008/10/31 23:59:59'

'/' vs '-' на RHS оператора сравнения '>'.

(1) 75,098 rows *expected*
(2) 0 rows *DIFFERENCE*
(3) 199 rows *simple case as expected*
(4) 199 rows *simple case as expected*

Вопрос - почему?

Ответы [ 3 ]

2 голосов
/ 13 ноября 2008

Краткий ответ: Используйте CAST(... AS DATE)

Длинный ответ:

С MySQL DATE тип :

Разрешен «расслабленный» синтаксис: любой знак пунктуации может использоваться как разделитель между частями даты или части времени Например, '98 -12-31 11:30:45 ', '98 .12.31 11 + 30 + 45', '98 / 12/31 11 * 30 * 45 'и '98 @ 12 @ 31 11 ^ 30 ^ 45 'эквивалентны.

В ваших примерах 1 и 2 вы используете ADDDATE ... это всегда возвращает дату с разделителем '-', независимо от формата ввода:

+-----------------------------------------------+
| ADDDATE('2008/10/31 23:59:59',INTERVAL 1 DAY) |
+-----------------------------------------------+
| 2008-11-01 23:59:59                           |
+-----------------------------------------------+

Вы также используете IFNULL, который теряет информацию о типе, поэтому при сравнении он сравнивается как строки.

Что вы можете сделать, это привести это к дате:

mysql> SELECT IFNULL(null, ADDDATE('2008/10/31 23:59:59',INTERVAL 1 DAY)) > '2008/10/31 23:59:59';
+-------------------------------------------------------------------------------------+
| IFNULL(null, ADDDATE('2008/10/31 23:59:59',INTERVAL 1 DAY)) > '2008/10/31 23:59:59' |
+-------------------------------------------------------------------------------------+
|                                                                                   0 |
+-------------------------------------------------------------------------------------+
1 row in set (0.00 sec)


mysql> SELECT CAST(IFNULL(null, ADDDATE('2008/10/31 23:59:59',INTERVAL 1 DAY)) AS DATE) > '2008/10/31 23:59:59';
+---------------------------------------------------------------------------------------------------+
| CAST(IFNULL(null, ADDDATE('2008/10/31 23:59:59',INTERVAL 1 DAY)) AS DATE) > '2008/10/31 23:59:59' |
+---------------------------------------------------------------------------------------------------+
|                                                                                                 1 |
+---------------------------------------------------------------------------------------------------+
0 голосов
/ 19 ноября 2008

Ссылка Краткий ответ: Используйте CAST (... КАК ДАТА)

LHS - это (1) и (2) то же самое, что RHS изменяет оценку и является строкой.

Ref "/" основанные даты.

Если '2008/10/31 23:59:59' является недопустимой датой, она потерпит неудачу в опциях (1), (3), (4), которые являются единственными удачными. Если '' 2008-10-31 23:59:59 'является недопустимой датой, в параметрах (1), (3), которые завершатся успешно, произойдет сбой.

0 голосов
/ 13 ноября 2008

Я не знаю много о mysql, но возможно ли, что основанная на "/" дата интерпретируется как "ГГГГ / ДД / ММ" и, таким образом, является полностью недействительной? В SQL Server я ожидал бы исключение в этом случае, но если mysql заменит какое-то значение «недопустимой даты», которое может объяснить разницу.

ГГГГ-ММ-ДД - официальный формат ISO. ГГГГ / ММ / ДД, о которых я никогда не слышал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...