web-dev-qa-db-fra.com

Comment comparer date-heure avec seulement la date dans SQL Server

Select * from [User] U
where  U.DateCreated = '2014-02-07'     

mais dans la base de données l'utilisateur a été créé sur 2014-02-07 12:30:47.220 et quand je ne mets que '2014-02-07'

Il ne montre aucune donnée

62
Muhabutti

Ne soyez pas tenté de faire des choses comme ça:

Select * from [User] U where convert(varchar(10),U.DateCreated, 120) = '2014-02-07'

C'est un meilleur moyen:

Select * from [User] U 
where U.DateCreated >= '2014-02-07' and U.DateCreated < dateadd(day,1,'2014-02-07')

voir: Sargable (la page a été retirée de Wikipedia)

EDIT + Il existe 2 raisons fondamentales pour éviter l'utilisation de fonctions sur des données dans la clause where (ou dans les conditions de jointure).

  1. Dans la plupart des cas, l'utilisation d'une fonction sur des données pour filtrer ou joindre supprime la possibilité pour l'optimiseur d'accéder à un index sur ce champ, rendant ainsi la requête plus lente (ou plus "coûteuse").
  2. L'autre est que, pour chaque ligne de données impliquée, au moins un calcul est effectué. Cela pourrait consister à ajouter des centaines, des milliers, voire des millions de calculs à la requête afin que nous puissions nous comparer à un critère unique tel que 2014-02-07. Il est beaucoup plus efficace de modifier les critères pour les adapter aux données. 

"Modifier les critères pour les adapter aux données" est ma façon de décrire "utiliser les prédicats SARGABLE"


Et n'utilisez pas entre les deux.

la meilleure pratique en ce qui concerne les dates et les heures consiste à éviter BETWEEN à to toujours utiliser le formulaire:

WHERE col> = '20120101' ET col <'20120201' Ce formulaire fonctionne avec tous types et toutes les précisions, que la partie temporelle soit ou non en vigueur.

http://sqlmag.com/t-sql/t-sql-best-practices-part-2 (Itzik Ben-Gan)

68
Used_By_Already

Si vous utilisez SQL Server 2008 ou une version ultérieure, vous pouvez utiliser le type de données de date:

SELECT *
FROM [User] U
WHERE CAST(U.DateCreated as DATE) = '2014-02-07'

Il convient de noter que si la colonne de date est indexée, elle utilisera toujours l’index et est SARGable. C'est un cas particulier pour les dates et les dates/heures.

enter image description here

Vous pouvez voir que SQL Server transforme cela en une clause> et <:

 enter image description here

Je viens d'essayer cela sur une grande table, avec un index secondaire sur la colonne de date, conformément aux commentaires de @ kobik et l'index est toujours utilisé, ce n'est pas le cas des exemples qui utilisent BETWEEN ou> = et <:

SELECT *
FROM [User] U
WHERE CAST(U.DateCreated as DATE) = '2016-07-05'

 showing index usage with secondary index

51
Steve Ford

Selon votre requête Select * from [User] U where U.DateCreated = '2014-02-07' 

SQL Server compare la date et l'heure exactes i.e (en comparant 2014-02-07 12:30:47.220 avec 2014-02-07 00:00:00.000 pour l'égalité). c'est pourquoi le résultat de la comparaison est faux

Par conséquent, lors de la comparaison des dates, vous devez également prendre en compte le temps. Vous pouvez utiliser
Select * from [User] U where U.DateCreated BETWEEN '2014-02-07' AND '2014-02-08'.

2
imdzeeshan

Bien sûr, c’est un vieux fil, mais il faut le compléter.

A partir de SQL 2008, vous pouvez utiliser le type de données DATE pour effectuer simplement:

SELECT CONVERT(DATE,GETDATE())

OR

Select * from [User] U
where  CONVERT(DATE,U.DateCreated) = '2014-02-07' 
0
Bikram