8
votes

T-SQL entre la confusion des dates

Je travaille avec T-SQL dans SQL Server 2000 et j'ai une table transactions code> qui a une colonne de date trandate code> définie comme DateTime, parmi de nombreuses autres colonnes qui sont Non pertinent pour cette question ..

La table est peuplée avec des transactions couvrant de nombreuses années. J'ai couru en code, test, qui m'a confondu. Il existe un simple SELECT CODE>, comme celui-ci: P>

SELECT TRANDATE, RECEIPTNUMBER FROM TRANSACTIONS WHERE TRANDATE BETWEEN '12/01/2010 00:00:00' and '12/31/2010 23:59:59' ORDER BY TRANDATE


2 commentaires

'12 / 31/2010 23:59:59 ' manquerait toujours les heures entre 12/31/2010 23:59:59 et 12/31/2010 23: 59: 59: 997 N'utilisez pas entre pour DateTimes utilisez > = et << / code>.


@Martin: merci. Et merci à tous les autres. Surtout @gserg qui a essentiellement répondu à ma question ci-dessous. Je ne peux pas upvote, il semble que je n'ai que 15 points, c'est pourquoi vous ne voyez pas tout (de moi). Mais maintenant, je comprends la base sur les réponses de chacun. Merci. J'ai du travail à faire! :-)


5 Réponses :


2
votes

Quel serait votre résultat attendu si je le ferais xxx

exactement: 12-31-2010 00:00:00

Alors pourquoi vous attendriez-vous être différent comme argument pour une requête?


0 commentaires

1
votes

Vous avez déjà répondu à votre propre question. Ce que vous avez observé est em> la façon dont SQL Server fonctionne.

Si c'est confirmation dont vous avez besoin, cette Document MSDN a suivi dire à ce sujet P>

lorsque la partie temporelle n'est pas spécifiée, elle Par défaut à 12h00. Notez qu'une ligne qui contient une partie de temps qui est Après 12h00. en 1998-0105 ne pas être retourné par cette requête parce que Il tombe en dehors de la gamme. P> blockQuote>

edit fort> p>

Quant à votre commentaire, une date d'heure est essentiellement une valeur de point flottante. P>

Le script suivant montre quels numéros SQL Server fonctionne avec.
40541.9749 (12/31/2010 23:23:59) Vous ne pouvez pas être inclus lorsque votre limite supérieure est 40541 (12/31/2010) P>

DECLARE @ADateTime1 DATETIME
DECLARE @ADateTime2 DATETIME
DECLARE @ADateTime1AsFloat FLOAT
DECLARE @ADateTime2AsFloat FLOAT

SET @ADateTime1 = '12/31/2010'
SET @ADateTime2 = '12/31/2010 23:23:59'

SET @ADateTime1AsFloat = CAST(@ADateTime1 AS FLOAT)
SET @ADateTime2AsFloat = CAST(@ADateTime2 AS FLOAT)

SELECT @ADateTime1AsFloat, @ADateTime2AsFloat


1 commentaires

Ok, mais c'est ma confusion. Vous êtes correct, je semble comprendre que ce que c'est ce que c'est ce que c'est ce que c'est ce qui m'a confondu ... le 12/31/2010 a 24 heures dedans et si j'ai une ligne de données avec un trandat de 2010-12 -31 18: 12: 54.000, pourquoi ne pas les entre les deux (sans heures dedans) en cueille-t-il? 12/31/2010 est toujours 12/11/2010 si le temps est 00:00:00 ou 18:12:54 ou 23:59:59!



14
votes

Une date est un point à temps, pas une période de temps.

'12 / 31/2010 ' est un point aussi. À savoir, il est minuit du 31 décembre.
Tout ce qui s'est passé après ce point est ignoré.
C'est exactement le comportement que vous voulez (même si vous n'avez pas encore compris cela).

Ne pensez pas que lorsque vous choisissez d'omettre la partie temporelle, il est supposé comme magiquement d'être "tout" . Ça va être "tous les zéros" , c'est-à-dire à minuit.

Si vous souhaitez inclure toute la journée de votre requête sans avoir à spécifier 23:59 : 59 (qui, au fait, exclut la dernière seconde de la journée , entre le moment 23:59:59 de la journée en cours et du moment 00:00:00 < / Code> du lendemain), vous pouvez le faire soit en utilisant des inégalités strictes (> , << / code>) délimité par les premiers points de temps que vous Don ' t veux: xxx

ou en comparant les valeurs de date coulées sur date : xxx

(il est correct de mettre ce type de coulé dans un clause, Il est sargable ).


0 commentaires

3
votes

'12 / 01/2010 'signifie '12 / 01/2010 00:00:00' et '12 / 31/2010 'signifie '12 / 31/2010 00:00:00'. C'est pourquoi les valeurs DateTime qui tombent plus tard la journée le 15/01/2010 sont exclues de vos résultats de la requête.


0 commentaires

4
votes

Comme vous l'avez découvert, si vous ne spécifiez pas de temps lors de la saisie d'une date, il est par défaut à minuit le matin de la date. SO 12/12/2010 s'arrête à minuit quand ce jour commence.

Pour obtenir toutes les dates pour le 12/11/2010, vous pouvez Simplifiez l'heure , comme vous l'avez fait, ou ajoutez un jour à la date de fin . Sans fois, le 1/1/2011 se termine à la course de minuit le 12/11/2010. Donc, vous pouvez faire entre le 12/1/2010 et le 1/1/2011 . Vous pouvez utiliser daadd pour ajouter la journée dans votre SQL si cela facilite la tâche.

Il existe un risque dans cette deuxième approche d'ajouter une journée. Vous obtiendrez des enregistrements pour le 1/1/2011 qui portent l'heure de 00:00:00.

Voici un moyen d'effectuer le daadd : xxx

alors vous utilisez @todate dans votre clause dans le entre de la manière habituelle.


0 commentaires