web-dev-qa-db-fra.com

La fonction de date Mysql ne fonctionne pas pour moins de

J'ai besoin d'obtenir tous les enregistrements égaux et inférieurs à 2012-12-28. J'ai utilisé la requête ci-dessous pour cela, Booking_time est le champ DATETIME. Il existe des enregistrements inférieurs à 2012-12-28, mais il ne renvoie aucune ligne. Quelqu'un a-t-il une idée?

SELECT * FROM ctx_bookings WHERE DATE(booking_time)<=2012-12-28 ORDER BY id ASC

Table déposée

+---------------------+
| booking_time        |
+---------------------+
| 2012-12-20 03:10:09 |
| 2012-12-25 02:10:04 |
+---------------------+

S'il vous plaît quelqu'un sait pourquoi cela se passe?

12
Gihan Dilusha

envelopper la valeur avec guillemet simple et cela fonctionnera

SELECT * 
FROM ctx_bookings 
WHERE DATE(booking_time) <= '2012-12-28' 
ORDER BY id ASC
39
John Woo

Comme indiqué dans Littéraux de date et heure :

MySQL reconnaît les valeurs DATE dans les formats suivants:

  • En tant que chaîne au format 'YYYY-MM-DD' ou 'YY-MM-DD'. Une syntaxe «assouplie» est autorisée: tout caractère de ponctuation peut être utilisé comme séparateur entre les parties de date. Par exemple, '2012-12-31', '2012/12/31', '2012^12^31' et '2012@12@31' sont équivalents.

  • En tant que chaîne sans délimiteurs au format 'YYYYMMDD' ou 'YYMMDD', à condition que la chaîne ait un sens en tant que date. Par exemple, '20070523' et '070523' sont interprétés comme étant '2007-05-23', mais '071332' est illégal (il comporte des parties de mois et de jour insensées) et devient '0000-00-00'.

  • Sous forme de nombre au format YYYYMMDD ou YYMMDD, à condition que le nombre ait un sens en tant que date. Par exemple, 19830905 et 830905 sont interprétés comme '1983-09-05'.

Comme @Barmar a commenté , votre expression littérale 2012-12-28 est évaluée en tant que l'arithmétique (2012 - 12) - 28, ce qui correspond à 1 972.

La réponse de/ @ JW. , vous pouvez citer cette expression pour obtenir un littéral de date valide (de la première forme, ci-dessus). Alternativement:

  • tout en continuant de citer le littéral, vous pouvez utiliser n'importe quel autre caractère de ponctuation (ou même aucun caractère) comme séparateur entre les parties de date:

    WHERE DATE(booking_time) <= '2012_12_28'
    WHERE DATE(booking_time) <= '20121228'
    
  • vous pouvez supprimer les délimiteurs et laisser votre littéral sans citation:

    WHERE DATE(booking_time) <= 20121228
    

Notez également que l'utilisation d'un critère de filtre comme celui-ci, qui utilise une fonction (dans ce cas, la fonction DATE()) sur une colonne, nécessite une analyse complète de la table afin d'évaluer cette fonction. Elle ne bénéficiera donc d'aucun index. Une alternative plus simple consisterait à filtrer plus explicitement la plage de valeurs de colonne (c'est-à-dire times) qui répondent à vos critères:

WHERE booking_time < '2012-12-28' + INTERVAL 1 DAY

Ceci est équivalent car toute heure tombant strictement avant le jour suivant aura nécessairement eu lieu au plus tard le jour de l’intérêt. Il est sargable, car la colonne est comparée à une expression constante (le résultat de l'opération + étant déterministe) et, par conséquent, un index supérieur à booking_time peut être parcouru pour rechercher immédiatement tous les enregistrements correspondants.

10
eggyal
 SELECT * FROM ctx_bookings WHERE DATE(booking_time)<='2012-12-28' ORDER BY id ASC

essayez ce compagnon 

1
Nipun Jain