I have been trying to call out all available dates from the last 3 months but unfortunately my "formula" seems to always leave out 1 day.
For example, if today is the 23-03-2023 and I want to return all the dates from the last 3 months I would expect to see everything from the 23-12-2022 but also INCLUDING the 23rd of December.
What I am doing is returning everything starting from today's date -3 months (so from the 24th of December) and excludes always today's date.
My database is on a SQL Server 2016.
select * from TABLE where DATE_COLUMN >= dateadd(month, -3, getdate())
2条答案
按热度按时间s3fp2yjn1#
Remove the time part from
GetDate()
before filtering:hmae6n7t2#
Use
cast(dateadd(month, -3, getdate()) as date)
to convert the filter value to adate
without a time part.GetDate()
returns the current date and time. When you compare adatetime
to adate
, both are treated asdatetime
values, ie with a date component.2023-12-31 01:00
will always be later than2023-12-31
so all entries up to that time will be lost.You can also use
cast(GetDate() as date)
.DATEADD
doesn't really care. Pick the expression that's easier to read.To exclude today's date you still need to cast to a
date
. :What about
cast(someDateTime as date)='2023-03-20'
?This would produce the correct results but have bad performance. If this was a non-date type, it would be very bad performance because the query engine wouldn't be able to use any indexes covering
someDateTime
. It would have to calculate the cast result for every single row and then filter them. This is called a non-SARGable query or, less scientifically, a Row-By-Agonizing-Row (RBAR).With date types, SQL Server will convert this into a date range query, equivalent to :
While this can use indexes, it can't use the statistics gathered for the actual stored dates so the server can still end up with a bad execution plan. If, for example, almost all rows pass the criteria using an index would be a waste of time. The server would have no way of knowing this though and would still use the index.
This is discussed at great length at Cast to date is sargable but is it a good idea? .
The solution in this case is to write the range expression explicitly: