Come interrogare il campo DATETIME utilizzando solo la data in Microsoft SQL Server?


90

Ho una tabella TEST con un DATETIMEcampo, come questo:

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

Quello che mi serve è una query che restituisca questa riga e ogni riga con data 19/03/2014, indipendentemente dall'ora. Ho provato a usare

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

Ma non restituisce righe. L'unico modo per farlo funzionare che ho trovato è fornire anche la parte dell'ora della data:

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

Risposte:


129

utilizzare l'intervallo o la funzione DateDiff

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

o

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

Altre opzioni sono:

  1. Se hai il controllo sullo schema del database e non hai bisogno dei dati temporali, rimuovilo.

  2. oppure, se devi mantenerlo, aggiungi un attributo di colonna calcolato che ha la parte dell'ora del valore della data rimossa ...

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

oppure, nelle versioni più recenti di SQL Server ...

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

quindi, puoi scrivere la tua query semplicemente:

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

Ok, funziona, ma mi chiedevo se esiste un modo più semplice.
delphirules

Bene, l'unico altro modo più semplice è non inserire i dati temporali nel database in primo luogo ... o creare un attributo calcolato che rimuove la parte del tempo e usarlo ... Ho aggiunto entrambe le opzioni alla mia risposta.
Charles Bretana

Ero preoccupato che il metodo DATEDIFF restituisse true (indesiderabilmente) per date come 19/4/2014 o 19/3/2015, poiché la parte "giorno" di quelle date è la stessa (e avevo visto rapporti altrove che lo avrebbero fatto agire in questo modo), ma l'ho testato su un database e sembra funzionare correttamente.
mono código

Sì, perché la DateDiff()funzione, in tutte le sue varianti, calcola e restituisce il numero di limiti di data che devono essere superati per passare da una data all'altra. Questo è il motivo DateDiff(day, '1Jan2016', '31Dec2017 23:259:59')per cui DateDiff(day, '31Dec2016 23:259:59', '1Jan2017 ') entrambi tornano 1.
Charles Bretana

56

Risposta semplice;

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

Anche se questa è una risposta valida, voglio sottolineare che mettere il campo della data che valuta dietro qualsiasi funzione porterà a problemi di prestazioni. Qualsiasi indice sulla data sarà inutile e il motore dovrà valutare ogni riga
jean


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

Questa è davvero una cattiva risposta. Per due ragioni.

1. Cosa succede con tempi come 23.59.59.700 ecc. Ci sono tempi maggiori di 23:59:59 e il giorno successivo.

2. Il comportamento dipende dal tipo di dati. La query si comporta in modo diverso per i tipi datetime / date / datetime2.

Testare con 23: 59: 59.999 rende le cose ancora peggiori perché a seconda del tipo di dati si ottengono arrotondamenti diversi.

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'))

- Per la data il valore è "tritato". - Per datetime il valore viene arrotondato alla data successiva. (Valore più vicino). - Per datetime2 il valore è preciso.


7

Questo funziona per me per il server MS SQL:

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

1

Prova questo

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

1

puoi provare questo

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

1
Grazie, ma penso che la soluzione più semplice sarebbe un confronto con il tempo, proprio come la soluzione precedente.
delphirules

0

Puoi usare questo approccio che tronca la parte di tempo:

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
Per favore aggiungi qualche spiegazione alla tua risposta!
ρss

Questo non funziona perché "2015/10/28 00: 00.001" è diverso da "2015/10/28"
PedroC88

0

Usalo semplicemente nella tua WHEREclausola.

La parte "SubmitDate" di seguito è il nome della colonna, quindi inserisci il tuo.

Ciò restituirà solo la parte "Anno" dei risultati, omettendo i minuti e così via.

Where datepart(year, SubmitDate) = '2017'

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

"col1" è il nome della colonna con data e ora
<nome della colonna> qui puoi cambiare il nome come desideri


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


0

Usa questo

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

-1

Prova questa query.

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');

Penso che questa sia la sintassi Oracle, non funziona su sql server
ceinmart

-2
SELECT * FROM test where DATEPART(year,[TIMESTAMP]) = '2018'  and  DATEPART(day,[TIMESTAMP]) = '16' and  DATEPART(month,[TIMESTAMP]) = '11'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.