Comment interroger le champ DATETIME en utilisant uniquement la date dans Microsoft SQL Server?


88

J'ai un TEST de table avec un DATETIMEchamp, comme ceci:

ID NAME DATE
1 TESTING 2014-03-19 20:05:20.000

Ce dont j'ai besoin d'une requête renvoyant cette ligne et chaque ligne avec la date 19/03/2014, quelle que soit l'heure. J'ai essayé d'utiliser

select * from test where date = '03/19/2014';

Mais il ne renvoie aucune ligne. La seule façon de le faire fonctionner que j'ai trouvée est de fournir également la partie heure de la date:

select * from test where date = '03/19/2014 20:03:02.000';

Réponses:


126

utiliser la plage ou la fonction DateDiff

 select * from test 
 where date between '03/19/2014' and '03/19/2014 23:59:59'

ou

 select * from test 
 where datediff(day, date, '03/19/2014') = 0

D'autres options sont:

  1. Si vous contrôlez le schéma de la base de données et que vous n'avez pas besoin des données de temps, supprimez-les.

  2. ou, si vous devez le conserver, ajoutez un attribut de colonne calculé dont la partie heure de la valeur de date est supprimée ...

Alter table Test Add DateOnly As DateAdd(day, datediff(day, 0, date), 0)

ou, dans les versions plus récentes de SQL Server ...

Alter table Test Add DateOnly As Cast(DateAdd(day, datediff(day, 0, date), 0) as Date)

ensuite, vous pouvez rédiger votre requête aussi simplement:

select * from test 
where DateOnly = '03/19/2014'

Ok, cela fonctionne, mais je me demandais s'il existe un moyen plus simple.
delphirules

Eh bien, le seul autre moyen plus simple est de ne pas mettre de données temporelles dans la base de données en premier lieu ... ou de créer un attribut calculé qui supprime la partie temporelle et de l'utiliser ... J'ai ajouté les deux options à ma réponse.
Charles Bretana

Je craignais que la méthode DATEDIFF renvoie true (de manière indésirable) pour des dates telles que 19/04/2014 ou 19/03/2015, car la partie `` jour '' de ces dates est la même (et j'avais vu des rapports ailleurs indiquant que cela agissez de cette manière), mais je l'ai testé sur une base de données et il semble fonctionner correctement.
mono código

Oui, car la DateDiff()fonction, dans toutes ses variantes, calcule et renvoie le nombre de frontières de date à franchir pour passer d'une date à l'autre. C'est pourquoi DateDiff(day, '1Jan2016', '31Dec2017 23:259:59')et les DateDiff(day, '31Dec2016 23:259:59', '1Jan2017 ') deux reviennent 1.
Charles Bretana

55

Réponse simple;

select * from test where cast ([date] as date) = '03/19/2014';

Bien que ce soit une réponse valable, je tiens à souligner que le fait de placer le champ de date derrière toute fonction entraînera des problèmes de performance. Tout index sur la date sera inutile et le moteur devra évaluer chaque ligne
jean


7
select * from test 
where date between '03/19/2014' and '03/19/2014 23:59:59'

C'est une très mauvaise réponse. Pour deux raisons.

1. Que se passe-t-il avec des heures comme 23.59.59.700 etc. Il y a des heures plus grandes que 23:59:59 et le jour suivant.

2. Le comportement dépend du type de données. La requête se comporte différemment pour les types datetime / date / datetime2.

Tester avec 23: 59: 59.999 rend les choses encore pires car selon le type de données, vous obtenez des arrondis différents.

select convert (varchar(40),convert(date      , '2014-03-19 23:59:59.999'))
select convert (varchar(40),convert(datetime  , '2014-03-19 23:59:59.999'))
select convert (varchar(40),convert(datetime2 , '2014-03-19 23:59:59.999'))

- Pour la date, la valeur est «hachée». - Pour datetime, la valeur est arrondie à la date suivante. (Valeur la plus proche). - Pour datetime2, la valeur est précise.


7

Cela fonctionne pour moi pour le serveur MS SQL:

select * from test
where 
year(date) = 2015
and month(date) = 10
and day(date)= 28 ;

1

Essaye ça

 select * from test where Convert(varchar, date,111)= '03/19/2014'

1

tu peux essayer ça

select * from test where DATEADD(dd, 0, DATEDIFF(dd, 0, date)) = '03/19/2014';

1
Merci, mais je pense que la solution la plus simple serait une comparaison avec le temps, tout comme la solution précédente.
delphirules

0

Vous pouvez utiliser cette approche qui tronque la partie temporelle:

select * from test
where convert(datetime,'03/19/2014',102) = DATEADD(dd, DATEDIFF(dd, 0, date), 0)

0
-- Reverse the date format
-- this false:
    select * from test where date = '28/10/2015'
-- this true:
    select * from test where date = '2015/10/28'

1
Veuillez ajouter quelques explications à votre réponse!
ρss

Cela ne fonctionne pas car '2015/10/28 00: 00.001' est différent de '2015/10/28'
PedroC88

0

Utilisez simplement ceci dans votre WHEREclause.

La partie «SubmitDate» ci-dessous est le nom de la colonne, alors insérez le vôtre.

Cela renverra uniquement la partie "Année" des résultats, en omettant les minutes, etc.

Where datepart(year, SubmitDate) = '2017'

0
select *, cast ([col1] as date) <name of the column> from test where date = 'mm/dd/yyyy'

"col1" est le nom de la colonne avec la date et l'heure
<nom de la colonne> ici vous pouvez changer le nom comme vous le souhaitez


0
select *
  from invoice
 where TRUNC(created_date) <=TRUNC(to_date('04-MAR-18 15:00:00','dd-mon-yy hh24:mi:ss'));


0

utilisez ceci

select * from TableName where DateTimeField > date() and  DateTimeField < date() + 1

-1

Testez cette requête.

SELECT *,DATE(chat_reg_date) AS is_date,TIME(chat_reg_time) AS is_time FROM chat WHERE chat_inbox_key='$chat_key' 
                         ORDER BY is_date DESC, is_time DESC

-1
select * from invoice where TRANS_DATE_D>= to_date  ('20170831115959','YYYYMMDDHH24MISS')
and TRANS_DATE_D<= to_date  ('20171031115959','YYYYMMDDHH24MISS');

Je pense que c'est la syntaxe Oracle, ne fonctionne pas sur le serveur SQL
ceinmart

-2
SELECT * FROM test where DATEPART(year,[TIMESTAMP]) = '2018'  and  DATEPART(day,[TIMESTAMP]) = '16' and  DATEPART(month,[TIMESTAMP]) = '11'
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.