Query SQL per selezionare le date tra due date


303

Ho un start_datee end_date. Voglio ottenere l'elenco delle date tra queste due date. Qualcuno può aiutarmi a indicare l'errore nella mia query.

select Date,TotalAllowance 
from Calculation 
where EmployeeId=1
  and Date between 2011/02/25 and 2011/02/27

Ecco Dateuna datetimevariabile

Risposte:


484

dovresti mettere quelle due date tra virgolette singole come ..

select Date, TotalAllowance from Calculation where EmployeeId = 1
             and Date between '2011/02/25' and '2011/02/27'

o può usare

select Date, TotalAllowance from Calculation where EmployeeId = 1
             and Date >= '2011/02/25' and Date <= '2011/02/27'

tieni presente che il primo appuntamento è inclusivo, ma il secondo è esclusivo, in quanto è effettivamente "27/02/2011 00:00:00"


42
SQL Server imposta automaticamente una data senza un'ora alle 00:00:00. Quindi questa query non restituirà nulla a partire dal 25/02/2011 e dal 26/02/2011 a mezzanotte?
Matt,

5
@Deepak, il tuo secondo bit dovrebbe dire> = e <=
IndoKnight il

3
Potresti menzionare che l'ordine è importante nella funzione TRA. Deve andare dal più vecchio a sinistra e più recente a destra. Questo non è intuitivo in quanto = è un operatore comparativo in sql e funziona sia per "EmployeeId = 1" o "1 = EmployeeId" nella clausola where.
Fi Horan,

@Matt, secondo la documentazione intermedia , se una riga avesse una data del 27/02/2011 senza un orario, tale riga equivale ad avere una data del 27/02/2011 alle 00:00 e verrebbe restituita nella query, perché è inferiore o uguale a 2011/02/27 00:00. Quindi, se non hai a che fare con il tempo, betweendovrebbe funzionare come previsto.
timctran,

@timctran Giusto, ma il 27/02/2011 00:00 è ciò che chiameremmo mezzanotte del 26/02/2011. Presumibilmente, la query significa includere il 27 ° nel set di risultati, ma una voce con un timestamp del 27/02/2011 alle 5:00 non sarebbe inclusa.
Sinjai

128

Poiché un datetime senza un determinato segmento di tempo avrà un valore di date 00:00:00.000, se vuoi essere sicuro di ottenere tutte le date nel tuo intervallo, devi fornire l'ora per la data di fine o aumentare la data di fine e utilizzare <.

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date between '2011/02/25' and '2011/02/27 23:59:59.999'

O

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date >= '2011/02/25' and Date < '2011/02/28'

O

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date >= '2011/02/25' and Date <= '2011/02/27 23:59:59.999'

NON utilizzare quanto segue, poiché potrebbe restituire alcuni record dal 28/02/2011 se i loro tempi sono 00: 00: 00.000.

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date between '2011/02/25' and '2011/02/28'

42
Le persone guardano ancora a queste domande e risposte, anche se in origine erano state poste qualche tempo fa. Sono venuto alla ricerca di una risposta e gran parte di ciò che ho visto qui era incompleto o assolutamente errato. La mia risposta non aiuterà il poster originale, ma potrebbe aiutare qualcuno, forse anche tra tre anni.
WelshDragon,

3
La tua risposta mi ha aiutato molto, @WelshDragon - Le altre risposte hanno escluso il fatto che il formato della data deve essere "semplice" sul server per ignorare le ore. "<= END_DATE" presuppone le 12:00, che non conoscevo. Stavo eseguendo una query con "... <= 01/01/2014" e non riuscivo a capire perché gli ordini in quella data non fossero visualizzati per il 1 °. Grazie mille.
Keith,

@WelshDragon - la tua risposta è un ottimo materiale per usare le date come clausola where. Grazie
Jack Frost,

cosa c'è di sbagliato se ritorna '2011/02/28 00:00:00.000'?
Muflix,

1
Provato oggi, potresti anche usare convert(date, Date) between '2011/02/25' and '2011/02/27'(almeno con un recente MS SQL Server). La convert()parte si occuperà di eliminare la parte temporale e il confronto tra le due parti funzionerà come previsto.
sensei,

14

Prova questo:

select Date,TotalAllowance from Calculation where EmployeeId=1
             and [Date] between '2011/02/25' and '2011/02/27'

I valori della data devono essere digitati come stringhe.

Per garantire una query a prova di futuro per SQL Server 2008 e versioni successive, è Datenecessario eseguire l'escape perché è una parola riservata nelle versioni successive.

Tieni presente che le date senza orari prendono la mezzanotte come impostazioni predefinite, quindi potresti non avere il valore corretto lì.


1
La data non è una parola chiave e non deve essere salvata. L'evidenziazione della sintassi è solo l'evidenziazione della sintassi, le parole chiave devono essere sfuggite solo se causano un errore di sintassi. È anche buona norma utilizzare la conversione esplicita anziché la conversione implicita delle costanti di datestring. - e data tra CAST ('2011/02 / 25'AS DATETIME) e CAST (' 2011/02 / 27'AS DATETIME)
tponthieux,

5
Naturalmente hai ragione se si tratta di SQL Server 2005, che l'OP ha taggato. Tuttavia, Date è riservato dal 2008 in poi, quindi per le prove future, non c'è nulla di male nel fuggire. Ho modificato la mia risposta.

1
Se specificasse la data singola per entrambi restituirebbe zero righe ma immagino che non sia un requisito
operativo

12
select * from table_name where col_Date between '2011/02/25' 
AND DATEADD(s,-1,DATEADD(d,1,'2011/02/27'))

Qui, prima aggiungi un giorno alla data di fine corrente, lo sarà 2011-02-28 00:00:00, quindi sottrai un secondo per stabilire la data di fine 2011-02-27 23:59:59. In questo modo, è possibile ottenere tutte le date tra gli intervalli indicati.

output:
2011/02/25
2011/02/26
2011/02/27

8
select * from test 
     where CAST(AddTime as datetime) between '2013/4/4' and '2014/4/4'

- se il tipo di dati è diverso


5

Questa query è utile per recuperare i valori tra la data corrente e le successive 3 date

SELECT * FROM tableName  WHERE columName 
BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 3 DAY)

Questo alla fine aggiungerà altri 3 giorni di buffer alla data corrente.


5

Questo è molto vecchio, ma date molte esperienze che ho avuto con le date, potresti prendere in considerazione questo: le persone usano impostazioni regionali diverse, come tali, alcune persone (e alcuni database / computer, a seconda delle impostazioni regionali) possono leggere questo data dell'11 / 12/2016 come l'11 dicembre 2016 o il 12 novembre 2016. Ancora di più, il 16/11/12 fornito al database MySQL verrà convertito internamente al 12 novembre 2016, mentre il database di Access in esecuzione su un computer con impostazione regionale del Regno Unito interpreterà e archiviarlo come 16 nov 2012.

Pertanto, ho reso esplicita la mia politica ogni volta che ho intenzione di interagire con date e database. Quindi fornisco sempre le mie domande e i miei codici di programmazione come segue:

SELECT FirstName FROM Students WHERE DoB >= '11 Dec 2016';

Si noti inoltre che Access accetterà il #, quindi:

SELECT FirstName FROM Students WHERE DoB >= #11 Dec 2016#;

ma MS SQL Server non lo farà, quindi uso sempre "" come sopra, che entrambi i database accettano.

E quando ottengo quella data da una variabile nel codice, converto sempre il risultato in stringa come segue:

"SELECT FirstName FROM Students WHERE DoB >= " & myDate.ToString("d MMM yyyy")

Sto scrivendo questo perché so che a volte alcuni programmatori potrebbero non essere abbastanza entusiasti di rilevare la conversione intrinseca. Non ci saranno errori per le date <13, solo risultati diversi!

Per quanto riguarda la domanda posta, aggiungi un giorno all'ultima data ed effettua il confronto come segue:

dated >= '11 Nov 2016' AND dated < '15 Nov 2016' 

le tue informazioni hanno contribuito a completare il mio compito. ci ho lavorato per più di 10 ore e nessuna delle risposte avrebbe funzionato per me. Quando concatengo come hai dimostrato il mio progetto funziona alla grande. ma la regola sembra essere quella di non scrivere un'istruzione SQL come questa. ogni volta che provo a impostare SqlCommand per aggiungere i parametri di data all'istruzione SQL i parametri non si collegheranno e ottengo l'errore che devo dichiarare "@startDate" e "@endDate". non riesco a superare questo problema. Ho provato il formato della data "gg MMM yyyy" che ha funzionato e ho anche provato "yyyy MMM dd" che ha anche eseguito lo stesso.
Dave Hampel,

Ottimo ha aiutato! Sopra sono esempi di codice. È sempre meglio dichiarare e utilizzare i parametri per evitare l'iniezione SQL. E sembra che tu sia già richiesto / protetto dalle regole del tuo progetto, il che è positivo.
Hannington Mambo,

4
select Date,TotalAllowance 
from Calculation 
where EmployeeId=1
  and convert(varchar(10),Date,111) between '2011/02/25' and '2011/02/27'

3

Prova ad inserire le date tra # # per esempio:

#2013/4/4# and #2013/4/20#

Ha funzionato per me.


1
Cosa fa # in questo contesto?
BK,

@BK è un delimitatore, come le virgolette per le stringhe. "Quando si forniscono valori a un'istruzione SQL, ad esempio come criteri di query, il loro tipo di dati deve essere correttamente definito da un" qualificatore ". Questo viene fatto racchiudendo il valore tra una coppia di caratteri appropriati." riferimento -> link
Aleksandar

1
@BK Se si tratta di una sintassi TSql, sarà necessario utilizzare le virgolette singole ( ' ) per ottenere ciò di cui hai bisogno. riferimenti * nozioni di base di sql-fontstuff.com * Inizio SQL - Paul Wilton, John Colby
Aleksandar

1
Non potrebbe essere più chiaro che la domanda riguarda SQL Server e T-SQL. T-SQL e SQL Server non accettano date tra tag hash, accetta date tra virgolette singole. Questa risposta è sbagliata
TT.

@TT. il numero di voti dice che ha ancora aiutato qualcuno. Al momento in cui ho scritto la mia risposta, la risposta accettata era già stata scelta. Tuttavia, ho scritto questo per aiutare chiunque potesse venire qui da Google o da qualche altra parte :)
Aleksandar

2

se la sua data tra 24 ore e inizia al mattino e termina alla sera dovrebbe aggiungere qualcosa di simile:

declare @Approval_date datetime
set @Approval_date =getdate()
Approval_date between @Approval_date +' 00:00:00.000' and @Approval_date +' 23:59:59.999'

1

migliore query per la data selezionata tra la data corrente e tre giorni precedenti :

  select Date,TotalAllowance from Calculation where EmployeeId=1 and Date BETWEEN       
DATE_SUB(CURDATE(), INTERVAL 3 DAY)  AND CURDATE() 

migliore query per la data selezionata tra la data corrente e i prossimi tre giorni :

  select Date,TotalAllowance from Calculation where EmployeeId=1 and Date BETWEEN   
   CURDATE()  AND DATE_ADD(CURDATE(), INTERVAL 3 DAY)   

1

Controlla di seguito Esempi: sia funzionanti che non funzionanti.

select * from tblUser Where    
convert(varchar(10),CreatedDate,111) between '2015/04/01' and '2016/04/01' //--**Working**

O

select * from tblUser Where
(CAST(CreatedDate AS DATETIME) between CAST('2015/04/01' AS DATETIME) And CAST('2016/4/30'AS DATETIME)) //--**Working**

O

select * from tblUser Where
(YEAR(CreatedDate) between YEAR('2015/04/01') And YEAR('2016/4/30')) 
//--**Working**

E di seguito non funziona:

select * from tblUser Where
Convert(Varchar(10),CreatedDate,111) >=  Convert(Varchar(10),'01-01-2015',111) and  Convert(Varchar(10),CreatedDate,111) <= Convert(Varchar(10),'31-12-2015',111) //--**Not Working**


select * from tblUser Where
(Convert(Varchar(10),CreatedDate,111) between Convert(Varchar(10),'01-01-2015',111) And Convert(Varchar(10),'31-12-2015',111)) //--**Not Working**

1

possiamo usare tra per mostrare i dati di due date ma questo cercherà tutti i dati e li confronterà in modo da rallentare il nostro processo per dati enormi, quindi suggerisco a tutti di usare datediff:

qry = "SELECT * FROM [calender] WHERE datediff(day,'" & dt & "',[date])>=0 and datediff(day,'" & dt2 & "',[date])<=0 "

qui il calendario è la tabella, dt come variabile della data di inizio e dt2 è la variabile della data di fine.


0

Mi piace usare la sintassi '1 MonthName 2015' per le date es:

   WHERE aa.AuditDate>='1 September 2015'
     AND aa.AuditDate<='30 September 2015'

per le date


0

Vorrei andare

select Date,TotalAllowance from Calculation where EmployeeId=1
             and Date >= '2011/02/25' and Date < DATEADD(d, 1, '2011/02/27')

La logica è che >=include l'intera data di inizio ed <esclude la data di fine, quindi aggiungiamo un'unità alla data di fine. Questo può adattarsi per mesi, ad esempio:

select Date, ... from ...
             where Date >= $start_month_day_1 and Date < DATEADD(m, 1, $end_month_day_1)

0
Select 
    * 
from 
    Calculation 
where 
    EmployeeId=1 and Date between #2011/02/25# and #2011/02/27#;

0

Puoi provare questo SQL

select * from employee where rec_date between '2017-09-01' and '2017-09-11' 


0
/****** Script for SelectTopNRows command from SSMS  ******/
SELECT TOP 10 [Id]
  ,[Id_parvandeh]
  ,[FirstName]
  ,[LastName]
  ,[RegDate]
  ,[Gilder]
  ,[Nationality]
  ,[Educ]
  ,[PhoneNumber]
  ,[DueInMashhad]

  ,[EzdevajDate]


  ,[MarriageStatus]
  ,[Gender]
  ,[Photo]

  ,[ModifiedOn]
  ,[CreatorIp]
   From
  [dbo].[Socials] where educ >= 3 or EzdevajDate  >= '1992/03/31' and EzdevajDate <= '2019/03/09' and MarriageStatus = 1

-2

è meglio scrivere in questo modo:

CREATE PROCEDURE dbo.Get_Data_By_Dates
(
    @EmployeeId INT = 1,
    @Start_Date DATE,
    @End_Date Date
)
AS
Select * FROM Calculation  
    where EmployeeId=@EmployeeId AND Test_Date BETWEEN @Start_Date AND @End_Date
RETURN

1
L'uso di una Stored-Procedure in questa situazione non ha alcun senso in quanto riduce orribilmente la flessibilità della query SQL, sarà così specifica, se non si desidera utilizzarla in una situazione davvero specifica, non utilizzare un Stored-Procedure - Inoltre ci sono molti miglioramenti disponibili per la tua Stored-Procedure che puoi trovare in questa comunità;).
shA.t,

-6
SELECT Date, TotalAllowance  
FROM Calculation  
WHERE EmployeeId = 1 
  AND Date BETWEEN to_date('2011/02/25','yyyy-mm-dd') 
               AND to_date ('2011/02/27','yyyy-mm-dd');

1
Probabilmente stavi pensando a Oracle SQL quando hai scritto questa risposta. Questo è valido in Oracle. Non tanto in SQL Server (da quello che posso vedere).
Charles Caldwell,
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.