MySQL compare la chaîne DATE avec la chaîne du champ DATETIME

89

J'ai une question: est-il possible de sélectionner dans une base de données MySQL en comparant une chaîne DATE "2010-04-29" avec des chaînes qui sont stockées comme DATETIME (2010-04-29 10:00)?

J'ai un sélecteur de date qui filtre les données et je voudrais interroger la table par le champ DATETIME comme ceci:

SELECT * FROM `calendar` WHERE startTime = '2010-04-29'"

... et j'aimerais obtenir la ligne dont la valeur DATETIME est "2010-04-29 10:00".

Aucune suggestion? Merci.

Manny Calavera
la source

Réponses:

159

Utilisez le suivant:

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'

Juste pour référence, j'ai une table d'enregistrement de 2 millions, j'ai exécuté une requête similaire. La réponse de Salils a pris 4,48 secondes, celle ci-dessus a pris 2,25 secondes.

Donc, si la table est GRANDE, je suggérerais plutôt cela.

David
la source
8
La première réponse est si lente, car elle doit formater chaque date / heure en une chaîne avant la comparaison. Votre va mieux, car il ne compare directement que la partie date du champ, mais il ne peut toujours pas utiliser l'index (testé sur mysql 5.1)
Marki555
1
Si les performances sont un problème, il peut être utile d'envisager de stocker la partie date et heure séparément, de sorte qu'un INDEX puisse être placé sur la partie date.
Thijs Riezebeek
1
Cette requête ne pourra pas utiliser l'index si elle startTimeest indexée.
Zamrony P. Juhara
42

Si vous souhaitez sélectionner toutes les lignes où la partie DATE d'une colonne DATETIME correspond à un certain littéral, vous ne pouvez pas le faire comme ceci:

WHERE startTime = '2010-04-29'

car MySQL ne peut pas comparer directement une DATE et une DATETIME. Ce que fait MySQL, il étend le littéral DATE donné avec l'heure «00: 00: 00». Alors ta condition devient

WHERE startTime = '2010-04-29 00:00:00'

Certainement pas ce que vous voulez!

La condition est une plage et doit donc être donnée comme plage. Il existe plusieurs possibilités:

WHERE startTime BETWEEN '2010-04-29 00:00:00' AND '2010-04-29 23:59:59'
WHERE startTime >= '2010-04-29' AND startTime < ('2010-04-29' + INTERVAL 1 DAY)

Il y a une petite possibilité pour le premier de se tromper - lorsque votre colonne DATETIME utilise une résolution inférieure à la seconde et qu'il y a un rendez-vous à 23:59:59 + epsilon. En général, je suggère d'utiliser la deuxième variante.

Les deux variantes peuvent utiliser un index sur startTime qui deviendra important lorsque la table grandira.

XL_
la source
9
La version de David n'est pas bonne, elle ne peut pas utiliser d'index. Pour utiliser un index, vous devez filtre sur la colonne directement, non pas sur un résultat d'une fonction ( date(), year(), datediff()ou tout similaire)
Marki555
Je cherchais comment mysql convertit la date en datetime, merci de l'effacer 00:00:00. maintenant mes résultats ont du sens
Accountant م
1
C'est une solution rapide correcte par rapport à d'autres réponses qui ne peuvent pas utiliser l'index s'il est disponible
Zamrony P. Juhara
23
SELECT * FROM `calendar` WHERE DATE_FORMAT(startTime, "%Y-%m-%d") = '2010-04-29'"

OU

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'
Salil
la source
23
C'est une question terrible. Evitez ça à tout prix. S'il existe un index sur startTime, il ne peut pas être utilisé par cette requête, car il applique une fonction à la colonne plutôt que de l'utiliser directement. Cela signifie que toute requête comme celle-ci nécessitera une analyse complète de la table. Sur une grande table, cela signifiera une requête extrêmement lente.
steveayre
Je suis d'accord, sa réponse est fausse - la bonne réponse a été publiée par David ci-dessous.
mindplay.dk
1
Veuillez utiliser la réponse de David, car c'est beaucoup plus rapide. Celui-ci est valide, mais pas bon pour la vitesse ...
xarlymg89
1
@ CarlosAlbertoMartínezGadea Cette version est lente car elle doit formater chaque valeur en chaîne avant la comparaison ... La version de David n'en a pas besoin, mais ne peut toujours pas utiliser d'index, elle n'est donc pas optimale. Voir la réponse de XL_ pour une version qui peut utiliser l'index. Malheureusement, il n'y a pas de meilleur moyen de le faire correctement dans mysql
Marki555
1
J'ai décliné cette réponse car la requête ne peut pas utiliser d'index, contrairement à la réponse de @ XL_.
pedromanoel
2
SELECT * FROM sample_table WHERE last_visit = DATE_FORMAT('2014-11-24 10:48:09','%Y-%m-%d %H:%i:%s')

ceci pour le format datetime dans mysql en utilisant DATE_FORMAT(date,format).

RT
la source
1
SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29';

cela aide, vous pouvez convertir les valeurs comme DATEavant de comparer.

Sarath
la source
0

Vous pouvez convertir le champ DATETIME en DATE comme suit:

SELECT * FROM `calendar` WHERE CAST(startTime AS DATE) = '2010-04-29'

C'est très efficace.

SGAmpere
la source
1
Non, ce n'est pas efficace non plus. cela ne pourra pas utiliser l'index s'il startTimeest indexé
Zamrony P. Juhara
-6
SELECT * FROM `calendar` WHERE startTime like '2010-04-29%'

Vous pouvez également utiliser des opérateurs de comparaison sur les dates MySQL si vous voulez trouver quelque chose après ou avant. C'est parce qu'ils sont écrits de telle manière (valeur la plus grande à la plus petite avec des zéros non significatifs) qu'un simple tri par chaîne les trie correctement.

Fletcher Moore
la source