Risposte:
L'operatore TRA è inclusivo.
Dai libri online:
TRA restituisce VERO se il valore di test_expression è maggiore o uguale al valore di begin_expression e minore o uguale al valore di end_expression.
DateTime Caveat
NB: con DateTimes devi stare attento; se viene fornita solo una data, il valore viene preso a partire dalla mezzanotte di quel giorno; per evitare tempi mancanti entro la data di fine o ripetere l'acquisizione dei dati del giorno seguente a mezzanotte in più intervalli, la data di fine dovrebbe essere di 3 millisecondi prima della mezzanotte del giorno successivo a quello attuale. 3 millisecondi perché non inferiore a questo e il valore verrà arrotondato alla mezzanotte del giorno successivo.
ad es. per ottenere tutti i valori entro giugno 2016 dovresti eseguire:
where myDateTime between '20160601' and DATEADD(millisecond, -3, '20160701')
vale a dire
where myDateTime between '20160601 00:00:00.000' and '20160630 23:59:59.997'
Sottraendo 3 ms da una data, sarai vulnerabile alle righe mancanti dalla finestra di 3 ms. La soluzione corretta è anche la più semplice:
where myDateTime >= '20160601' AND myDateTime < '20160701'
CONVERT
un datetime a una data , poiché ciò renderà gli indici inutili. Usa lo standard WHERE OrderDate >= '20160601' AND OrderDate < '20160701'
. Inoltre, assicurati di utilizzare yyyymmdd
, poiché yyyy-mm-dd
dipende dalle mdy, dmy, ymd, ydm, myd, and dym
impostazioni locali e verrà interpretato erroneamente in base alle impostazioni del tuo server .
Sì, ma fai attenzione quando usi tra per le date.
BETWEEN '20090101' AND '20090131'
è davvero interpretato come 12am o
BETWEEN '20090101 00:00:00' AND '20090131 00:00:00'
così mancherà tutto ciò che è accaduto durante il giorno del 31 gennaio. In questo caso, dovrai usare:
myDate >= '20090101 00:00:00' AND myDate < '20090201 00:00:00' --CORRECT!
o
BETWEEN '20090101 00:00:00' AND '20090131 23:59:59' --WRONG! (see update!)
AGGIORNAMENTO : È possibile creare dei record nell'ultimo secondo della giornata, con un datetime fino al 20090101 23:59:59.997
!!
Per questo motivo, l' BETWEEN (firstday) AND (lastday 23:59:59)
approccio non è raccomandato.
Usa myDate >= (firstday) AND myDate < (Lastday+1)
invece l' approccio.
WHERE col BETWEEN 'a' AND 'z'
escluderanno ad esempio la maggior parte delle righe z.
BETWEEN 5 AND 10
non include 10.2
...
CAST
zione del datetime
come DATE
avrebbe funzionato: CAST(DATE_TIME_COL AS DATE) BETWEEN '01/01/2009' AND '01/31/2009'
.
It is entirely possible to have records created within that last second of the day, with a datetime as late as 01/01/2009 23:59:59.997
<- non puoi usare solo allora AND '01/31/2009 23:59:59.99999999'
o comunque sono necessari molti 9
Esempio reale da SQL Server 2008.
Dati di origine:
ID Start
1 2010-04-30 00:00:01.000
2 2010-04-02 00:00:00.000
3 2010-05-01 00:00:00.000
4 2010-07-31 00:00:00.000
Query:
SELECT
*
FROM
tbl
WHERE
Start BETWEEN '2010-04-01 00:00:00' AND '2010-05-01 00:00:00'
risultati:
ID Start
1 2010-04-30 00:00:01.000
2 2010-04-02 00:00:00.000
ID = 3
esclusa? Il suo Start
valore è uguale al BETWEEN
valore con limite superiore ed BETWEEN
è un intervallo inclusivo, non un intervallo con limite superiore esclusivo.
se lo colpisci e non vuoi davvero provare a gestire l'aggiunta di un giorno nel codice, lascia che il DB lo faccia ..
myDate >= '20090101 00:00:00' AND myDate < DATEADD(day,1,'20090101 00:00:00')
Se includi la parte temporale: assicurati che faccia riferimento a mezzanotte. Altrimenti puoi semplicemente omettere il tempo:
myDate >= '20090101' AND myDate < DATEADD(day,1,'20090101')
e non preoccuparti.
TRA (Transact-SQL)
Specifica un intervallo ( n ) ( inclusivo ) da testare.
test_expression [ NOT ] BETWEEN begin_expression AND end_expression
argomenti
test_expression
Espressione da testare nell'intervallo definito da begin_expression e end_expression. test_expression deve essere dello stesso tipo di dati sia begin_expression che end_expression.
NOT
Specifica che il risultato del predicato deve essere negato.
begin_expression
Qualsiasi espressione valida. begin_expression deve essere dello stesso tipo di dati di test_expression e end_expression.
end_expression
Qualsiasi espressione valida. end_expression deve essere dello stesso tipo di dati di test_expression e begin_expression.
AND
Agisce come segnaposto che indica test_expression deve essere compreso nell'intervallo indicato da begin_expression e end_expression.
Osservazioni
Per specificare un intervallo esclusivo, utilizzare gli operatori maggiore di (>) e minore di (<). Se qualsiasi input per il predicato TRA o NON TRA è NULL, il risultato è SCONOSCIUTO.
Valore risultato
TRA restituisce VERO se il valore di test_expression è maggiore o uguale al valore di begin_expression e minore o uguale al valore di end_expression.
NON TRA restituisce VERO se il valore di test_expression è inferiore al valore di begin_expression o maggiore del valore di end_expression.
Se il tipo di dati della colonna è datetime, è possibile procedere come segue per eliminare l'ora dal datetime e confrontare solo tra intervalli di date.
where cast(getdate() as date) between cast(loginTime as date) and cast(logoutTime as date)
Include i confini.
declare @startDate date = cast('15-NOV-2016' as date)
declare @endDate date = cast('30-NOV-2016' as date)
create table #test (c1 date)
insert into #test values(cast('15-NOV-2016' as date))
insert into #test values(cast('20-NOV-2016' as date))
insert into #test values(cast('30-NOV-2016' as date))
select * from #test where c1 between @startDate and @endDate
drop table #test
RESULT c1
2016-11-15
2016-11-20
2016-11-30
declare @r1 int = 10
declare @r2 int = 15
create table #test1 (c1 int)
insert into #test1 values(10)
insert into #test1 values(15)
insert into #test1 values(11)
select * from #test1 where c1 between @r1 and @r2
drop table #test1
RESULT c1
10
11
15
L'ho sempre usato:
DOVE myDate TRA startDate AND (endDate + 1)