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';
delphirules
la source

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'
Charles Bretana
la source
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';
Kabcha
la source
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.

Ben
la source
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 ;
Jeroen Krah
la source
1

Essaye ça

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

tu peux essayer ça

select * from test where DATEADD(dd, 0, DATEDIFF(dd, 0, date)) = '03/19/2014';
Enfer
la source
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)
Tim Schmelter
la source
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'
Sherif Hamdy
la source
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'
user8161541
la source
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

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

Il y a un problème avec les dates et les langues et la façon de l'éviter est de demander des dates avec ce format AAAAMMJJ.

Cette manière ci-dessous devrait être la plus rapide selon le lien ci-dessous. J'ai vérifié dans SQL Server 2012 et j'accepte le lien.

select * from test where date >= '20141903' AND date < DATEADD(DAY, 1, '20141903');
mako
la source
0

utilisez ceci

select * from TableName where DateTimeField > date() and  DateTimeField < date() + 1
Akhil
la source
-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
Programer_saeed
la source
-1
select * from invoice where TRANS_DATE_D>= to_date  ('20170831115959','YYYYMMDDHH24MISS')
and TRANS_DATE_D<= to_date  ('20171031115959','YYYYMMDDHH24MISS');
khairollah royesh
la source
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'
Kalidas
la source