Je suis confronté à un résultat de requête étrange et je veux vous requestr pourquoi je suis confronté à ce problème.
Je stocke certaines données datetime dans TestTable comme suit:
creation_time ----------------------- 2010-07-10 00:01:43.000 2010-07-11 00:01:43.000 2010-07-12 00:01:43.000
Cette table est créée et remplie comme suit:
create table TestTable(creation_time datetime); Insert into TestTable values('2010-07-10 00:01:43.000'); Insert into TestTable values('2010-07-11 00:01:43.000'); Insert into TestTable values('2010-07-12 00:01:43.000');
quand j'exécute cette requête, j'obtiens deux rangées seulement au lieu de trois comme je m'y attendais:
SELECT * FROM TestTable WHERE creation_time BETWEEN CONVERT(VARCHAR(10),'2010-07-10',111) -- remove time part and CONVERT(VARCHAR(10),'2010-07-12',111) -- remove time part
Ou si j'exécute cette requête, le même problème ..
SELECT * FROM TestTable WHERE CONVERT(datetime,creation_time,111) BETWEEN CONVERT(VARCHAR(10),'2010-07-10',111) -- remove time part and CONVERT(VARCHAR(10),'2010-07-12',111) -- remove time part
Ma question :
Merci .
Vous devez également supprimer la partie time de creation_time. Utilisez simplement le même CONVERT
si cela fonctionne.
Actuellement, vous requestz si le 2010-07-12 00: 01: 43.000 est inférieur au 2010-07-12 00: 00: 00.000, ce qui n'est pas vrai.
il n'affiche pas la date parce que vous avez supprimé la partie heure, ce qui rendrait la date équivalente à '2010-07-12 00:00:00.000'
et puisque la dernière rangée est plus grande que celle-ci, elle n'est donc pas affichée dans le résultats de la requête.
Votre script devrait ressembler à ceci:
SELECT * FROM TestTable WHERE creation_time BETWEEN convert(datetime, convert(char, '2010-07-10', 106))-- remove time part and **DATEADD**(day, 1, convert(datetime, convert(char, '2010-07-**11**', 106))) -- remove time part and add 1 day
Ce script renverra tous entre 2010-07-10 00:00:00 et 2010-07-12 00:00:00. Fondamentalement, cela signifie tous les éléments créés en 2 jours: 2010-07-10 et 2010-07-11.
La conversion de colonnes dans votre table pour la comparaison peut être coûteuse et ne pas utiliser les index. Si vous avez un million de lignes dans votre table et que vous avez un index sur creation_time, vous allez effectuer une parsing d'index et convertir toutes les valeurs de million en une string pour comparaison.
Je trouve préférable d'utiliser> = la date de début et <(date de fin + 1 jour):
SELECT * FROM TestTable WHERE creation_time >= '2010-07-10' AND creation_time < dateadd(day, 1, '2010-07-12')
Et la raison pour laquelle votre second ne fonctionne pas est que le format 111 utilise des barres obliques ("2010/07/10"), le format 120 utilise des tirets ("2010-07-10"). Vos convertis ne font rien à vos dates de début et de fin parce que vous convertissez une string en varchar, pas une date. Si vous avez fait cela, cela pourrait fonctionner, mais je reorderais quand même de ne pas faire la conversion:
SELECT * FROM TestTable WHERE CONVERT(datetime, creation_time, 111) BETWEEN CONVERT(VARCHAR(10), CONVERT(datetime, '2010-07-10'), 111) -- remove time part and CONVERT(VARCHAR(10), CONVERT(datetime, '2010-07-12'), 111) -- remove time part
Date / heure comprise entre le 7/10/2010 et le 7/12/2010:
SELECT * FROM TestTable WHERE creation_time BETWEEN CONVERT(VARCHAR,'2010-07-10',101) -- remove time part and CONVERT(VARCHAR,'2010-07-13',101) -- remove time part