Comment puis-je tronquer une datetime dans SQL Server?

Quelle est la meilleure façon de tronquer une valeur datetime (comme supprimer heures minutes et secondes) dans SQL Server 2008?

par exemple:

declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)

-----------------------
2009-05-28 00:00:00.000
241
demandé sur Jason Plank 2009-05-29 01:28:03

13 réponses

cela continue à recueillir fréquemment des votes supplémentaires, même plusieurs années plus tard, et je dois donc le mettre à jour pour les versions modernes de Sql Server. Pour Sql Server 2008 et plus tard, c'est simple:

cast(getDate() As Date)

Notez que les trois derniers paragraphes près du bas s'appliquent toujours, et vous avez souvent besoin de prendre du recul et de trouver un moyen d'éviter la fonte en premier lieu.

mais il y a d'autres façons d'accomplir ceci, aussi. Voici les plus commun.

dans Le bon sens (nouveau depuis Sql Server 2008):

cast(getdate() As Date)

dans Le bon sens (ancien):

dateadd(dd, datediff(dd,0, getDate()), 0)

C'est plus ancien maintenant, mais il est toujours intéressant de savoir parce qu'il peut également s'adapter facilement pour d'autres points de temps, comme le premier moment du mois, minute, heure, ou année.

cette façon correcte utilise des fonctions documentées qui font partie de la ANSI standard et sont garantis de fonctionner, mais il peut être un peu plus lent. Il fonctionne en trouvant combien de jours il y a du jour 0 au jour courant, et en ajoutant que beaucoup de jours en arrière au jour 0. Il fonctionnera peu importe comment votre datetime est stocké et peu importe ce que votre locale est.

"1519120920 rapide:

cast(floor(cast(getdate() as float)) as datetime)

cela fonctionne parce que les colonnes datetime sont stockées sous forme de valeurs binaires de 8 octets. Les jeter à flotteur, d'un étage à supprimer la fraction, et la portion de temps des valeurs ont disparu quand vous les rejetez à datetime. C'est juste un petit changement sans logique compliquée et c'est très rapide.

soyez conscient que cela dépend d'un détail D'implémentation Microsoft est libre de changer à tout moment, même dans une mise à jour de service automatique. Il n'est également pas très portable. Dans la pratique, il est très peu probable que cette mise en œuvre change dans un avenir proche, mais il est important d'être conscient le danger si vous choisissez de l'utiliser. Et maintenant que nous avons l'option de lancer comme date, c'est rarement nécessaire.

de La mauvaise façon:

cast(convert(char(11), getdate(), 113) as datetime)

la mauvaise façon fonctionne en convertissant en une chaîne, en tronquant la chaîne, et en convertissant de nouveau en datetime. C'est wrong , pour deux raisons: 1)Il ne fonctionne peut-être pas à travers tous les endroits et 2) Il s'agit de la façon la plus lente possible de le faire... et pas seulement une peu; c'est comme un ordre de grandeur ou deux plus lent que les autres options.


mettre à jour cela a été d'obtenir quelques votes ces derniers temps, et donc je tiens à ajouter à cela que depuis que j'ai posté ceci j'ai vu quelques preuves assez solides que Sql Server va optimiser loin la différence de performance entre" correct "chemin et le" rapide " chemin, ce qui signifie que vous devriez maintenant favoriser le premier.

dans tous les cas, vous voulez écrivez vos questions pour éviter la nécessité de le faire en premier lieu . Il est très rare que vous fassiez ce travail sur la base de données.

dans la plupart des endroits, la base de données est déjà votre goulot d'étranglement. C'est généralement le serveur qui coûte le plus cher pour ajouter du matériel pour améliorer les performances et le plus difficile pour obtenir ces ajouts (vous devez équilibrer les disques avec la mémoire, par exemple). C'est aussi le plus difficile à l'échelle vers l'extérieur, à la fois techniquement et d'un point de vue commercial, il est beaucoup plus facile techniquement d'ajouter un serveur web ou d'application qu'un serveur de base de données et même si c'était faux, vous ne payez pas 20 000 $+ par licence de serveur pour IIS ou apache.

le point que j'essaie de faire est que chaque fois que possible vous devriez faire ce travail au niveau de l'application. Le seulement temps vous devriez jamais vous trouver tronquer un datetime sur le serveur Sql est quand vous avez besoin de grouper par le day, et même alors vous devriez probablement avoir une colonne supplémentaire mise en place comme une colonne calculée, maintenue à l'heure d'insertion/mise à jour, ou maintenue dans la logique d'application. Retirez de votre base de données ce travail qui casse l'index et le processeur.

428
répondu Joel Coehoorn 2016-04-13 18:32:01

pour SQL Server 2008 seulement

CAST(@SomeDateTime AS Date) 

puis la lancer à nouveau à datetime si vous voulez

CAST(CAST(@SomeDateTime AS Date) As datetime)
43
répondu DJ. 2009-05-28 22:15:46

juste pour une réponse plus complète, voici une façon de faire pour tronquer vers le bas n'importe quelle partie de la date et y compris les minutes (remplacer GETDATE() par la date pour tronquer).

c'est différent de la réponse acceptée en ce que vous pouvez utiliser non seulement dd (jours), mais n'importe laquelle des parties de date (voir ici ):

dateadd(minute, datediff(minute, 0, GETDATE()), 0)

noter que dans l'expression ci-dessus, le 0 est une date constante sur le début de l'année (1900-01-01). Si vous devez tronquer des pièces plus petites, comme des secondes ou des millisecondes, vous devez prendre une date constante qui est plus proche de la date à tronquer pour éviter un débordement.

19
répondu Lucero 2011-05-31 12:02:27

L'extrait que j'ai trouvé sur le web quand j'ai dû le faire était:

 dateadd(dd,0, datediff(dd,0, YOURDATE))
 e.g.
 dateadd(dd,0, datediff(dd,0, getDate()))
7
répondu Tom Ritter 2009-05-28 21:30:17

dans SQl 2005 votre fonction trunc_date pourrait être écrite comme ceci.

(1)

CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
    CAST(FLOOR( CAST( @date AS FLOAT ) )AS DATETIME)
END

La première méthode est beaucoup plus propre. Il n'utilise que 3 appels de méthode incluant la distribution finale () et n'effectue aucune concaténation de chaîne, ce qui est un plus automatique. En outre, il n'y a pas d'énormes moulages de type ici. Si vous pouvez imaginer que la date / l'heure des timbres peut être représentée, alors convertir des dates en nombres et revenir aux dates est un assez facile processus.

(2)

CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
      SELECT CONVERT(varchar, @date,112)
END

si vous êtes préoccupé par l'implémentation de datetimes (2) ou (3) par microsoft, cela pourrait être ok.

(3)

CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
SELECT CAST((STR( YEAR( @date ) ) + '/' +STR( MONTH( @date ) ) + '/' +STR( DAY(@date ) )
) AS DATETIME
END

Troisièmement, la méthode plus verbeuse. Pour ce faire, il faut décomposer la date en parties de l'Année, du mois et du jour, les regrouper dans le format "AAAA/mm/JJ", puis les reporter à une date. Cette méthode implique 7 appels de méthode incluant la distribution finale (), mentionner la concaténation de chaîne.

1
répondu AlejandroR 2009-06-25 04:14:47
CONVERT(DATE, <yourdatetime>) or CONVERT(DATE, GetDate()) or CONVERT(DATE, CURRENT_TIMESTAMP)
1
répondu Dean 2011-10-10 14:36:01

choisir cast (cast (getdate () as float)) comme datetime) Référence: http://microsoftmiles.blogspot.com/2006/11/remove-time-from-datetime-in-sql-server.html

0
répondu Sudhir Bastakoti 2011-11-27 12:34:28

pour ceux d'entre vous qui sont venus ici à la recherche d'un moyen de tronquer un champ DATETIME à quelque chose de moins d'une journée entière, par exemple chaque minute, Vous pouvez utiliser ceci:

SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) + (FLOOR((CAST(GETDATE() AS FLOAT) - FLOOR(CAST(GETDATE() AS FLOAT))) * 1440.0) + (3.0/86400000.0)) / 1440.0 AS DATETIME)

donc si aujourd'hui était 2010-11-26 14:54:43.123 alors cela reviendrait 2010-11-26 14:54:00.000 .

pour changer l'intervalle qu'il traverse, remplacer 1440.0 par le nombre d'intervalles par jour, par exemple:

24hrs          =   24.0  (for every hour)
24hrs / 0.5hrs =   48.0  (for every half hour)
24hrs / (1/60) = 1440.0  (for every minute)

(Toujours mettre un .0 sur la fin de implicitement jeté sur un char.)


pour ceux d'entre vous qui se demandent à quoi sert le (3.0/86400000) dans mon calcul, SQL Server 2005 ne semble pas lancer de FLOAT à DATETIME avec précision, donc cela ajoute 3 millisecondes avant de le couvrir.

0
répondu BG100 2012-02-22 13:03:58

cette requête devrait vous donner un résultat équivalent à trunc(sysdate) dans Oracle.

SELECT  * 
FROM    your_table
WHERE   CONVERT(varchar(12), your_column_name, 101)
      = CONVERT(varchar(12), GETDATE(), 101)

Espérons que cette aide!

0
répondu Sandeep Gaadhe 2012-05-23 15:37:29

vous pouvez également extraire la date using Substring de la variable datetime et renvoyer à datetime ignorera time part.

declare @SomeDate datetime = '2009-05-28 16:30:22'
SELECT cast(substring(convert(varchar(12),@SomeDate,111),0,12) as Datetime) 

aussi, vous pouvez accéder à des parties de la variable datetime et les fusionner à une date tronquée de construction, quelque chose comme ceci:

SELECT cast(DATENAME(year, @Somedate) + '-' + 
       Convert(varchar(2),DATEPART(month, @Somedate)) + '-' +
       DATENAME(day, @Somedate) 
       as datetime)
0
répondu NeverHopeless 2012-11-07 07:36:41

Oracle:

TRUNC(SYSDATE, 'MONTH')

SQL Server:

DATEADD(DAY, - DATEPART(DAY, DateField) + 1, DateField)

pourrait être utilisé de la même manière pour tronquer les minutes ou les heures à partir d'une date.

0
répondu Markus 2014-02-14 08:46:01

, vous pourriez faire ce SQL (2008):

declare @SomeDate date = getdate ()

select @SomeDate

2009-05-28

0
répondu Hagai Danenberg-Lerner 2014-08-01 15:02:10

TRUNC(aDate, 'DD') va tronquer le min, sec et h

SRC: http://www.techonthenet.com/oracle/functions/trunc_date.php

-1
répondu Ramnath 2011-11-27 12:16:56