I want to select all records from a table Log where the DateAndTime field values (of type datetime) are for the day before today, whatever day it is.
So if today is 2011-06-08, I want to select all rows where DateAndTime is greater than or equal to 2011-06-07 00:00:00 and also less than 2011-06-08 00:00:00.
I'm guessing the potential pitfall here would be it's behaviour on the 1st day of the month, as obviously a date like 2011-06-00 is invalid, and should be 2011-05-31.
For SQL Server 2008 you can use this.
select *
from [log]
where cast(DateAndTime as date) = cast(getdate()-1 as date)
Pre 2008 you can use this
select *
from [log]
where DateAndTime >= dateadd(d, datediff(d, 0, getdate())-1, 0) and
DateAndTime < dateadd(d, datediff(d, 0, getdate()), 0)
Related on DBA: Cast to date is sargable but is it a good idea?
SELECT * FROM Log
WHERE DateAndTime >= DATEADD(DAY,-1, CAST(GETDATE() AS DATE))
AND DateAndTime < CAST(CAST(GETDATE() AS DATE) AS DATETIME)
This example assumes SQL Server:
select *
from log
where convert(varchar(8), DateAndTime , 112) = convert(varchar(8), getdate()-1, 112)
Essentially, convert the date to yyyymmdd (the 112 parameter) and then check it is equal to yesterday's date (getdate()-1), also converted to yyyymmdd.
Assuming SQL Server
declare #today date
set #today = GETDATE()
select * from Log where DateAndTime between DATEADD(dd, -1, #today ) and #today
It should include conditional operator and not between .
Otherwise it includes today's records as well.
Declare #today date
Set #today = GETDATE()
Select YourcolumnNames from log
Where DateAndTime >= DATEADD(dd, -1, #today ) and DateAndTime < DATEADD(dd, -1, #today )
Moreover, you should mention the column name and * should be avoided in the select statement. This can improve the performance
Related
I have a query -
SELECT * FROM TABLE WHERE Date >= DATEADD (day, -7, -getdate()) AND Date <= getdate();
This would return all records for each day except day 7. If I ran this query on a Sunday at 17:00 it would only produce results going back to Monday 17:00. How could I include results from Monday 08:00.
Try it like this:
SELECT *
FROM SomeWhere
WHERE [Date] > DATEADD(HOUR,8,DATEADD(DAY, -7, CAST(CAST(GETDATE() AS DATE) AS DATETIME))) --7 days back, 8 o'clock
AND [Date] <= GETDATE(); --now
That's because you are comparing date+time, not only date.
If you want to include all days, you can trunc the time-portion from getdate(): you can accomplish that with a conversion to date:
SELECT * FROM TABLE
WHERE Date >= DATEADD (day, -7, -convert(date, getdate())
AND Date <= convert(date, getdate());
If you want to start from 8 in the morning, the best is to add again 8 hours to getdate.
declare #t datetime = dateadd(HH, 8, convert(datetime, convert(date, getdate())))
SELECT * FROM TABLE
WHERE Date >= DATEADD (day, -7, -#t) AND Date <= #t;
NOTE: with the conversion convert(date, getdate()) you get a datatype date and you cannot add hours directly to it; you must re-convert it to datetime.
Sounds like you want to remove the time. Correct? If so then do the following.
SELECT * FROM TABLE WHERE Date >= (DATEADD (day, -7, -getdate()) AND Date DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0))
I wrote a query to obtain First of month,
SELECT DATEADD(DAY, -(DATEPART(DAY,GETDATE())-1), GETDATE()) as First_Of_Month;
for which i do get the appropriate output, but my time stamp shows the current time.
Here's what I am doing in the query, hope i make sense.
using datepart i calculated the no. of days (int) between the 1st and today (27-1 =26)
Then using dateadd function, i added "-datepart" to get the first of the month.
This is just changing the date, what should i look at or read about in order to change the time. I am assuming that it would have something to do with 19000101
For SQL Server 2012 (thanks adrift and i-one)
DECLARE #now DATETIME = CURRENT_TIMESTAMP;
SELECT DATEADD(DAY, 1, EOMONTH(#now, -1));
-- or
SELECT DATEFROMPARTS(YEAR(#now), MONTH(#now), 1);
For SQL Server 2008+
DECLARE #now DATETIME = CURRENT_TIMESTAMP;
-- This shorthand works:
SELECT CONVERT(DATE, #now+1-DAY(#now));
-- But I prefer to be more explicit, instead of relying on
-- shorthand date math (which doesn't work in all scenarios):
SELECT CONVERT(DATE, DATEADD(DAY, 1-DAY(#now), #now));
For SQL Server 2005
SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()),0);
A caveat if you're using this SQL Server 2005 method: you need to be careful about using expressions involving DATEDIFF in queries. SQL Server can transpose the arguments and lead to horrible estimates - as seen here. It might actually be safer to take the slightly less efficient string approach:
SELECT CONVERT(DATETIME, CONVERT(CHAR(6), GETDATE(), 112) + '01');
SELECT convert(varchar(10),DATEADD(DAY, - (DATEPART(DAY,GETDATE())-1), GETDATE()),120)+' 00:00:00' as First_Of_Month;
Just the date
DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)
So for a month it is:
DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0) AS FirstDatetimeOfMonthmm,
I think the easiest way is to cast the result to date:
SELECT cast(DATEADD(DAY, -(DATEPART(DAY,GETDATE())-1), GETDATE()) as date) as First_Of_Month
One alternative:
SELECT cast(
cast(datepart(yyyy, getdate()) as varchar)
+ '-'
+ cast(datepart(mm, getdate()) as varchar) + '-01 00:00:00'
as datetime)
Build up the date from year/month components, then tack on the 1st and midnight.
SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0) as First_Of_Month;
Try following code:
SELECT CAST(CAST(GETDATE() AS DATE) AS DATETIME) AS StartDateTime,
DATEADD(ms, -3, CAST(CONVERT(date, DATEADD (DAY,1,GETDATE())) AS varchar(10))) AS EndDateTime
Result:
StartDateTime
EndDateTime
2022-05-23 00:00:00.000
2022-05-23 23:59:59.997
I have a simple query that pulls a payout report for our day. I'd like to automate this to send every night, however I want the report to run for That day 12:00AM - 11:59 PM daily... I will be sending the reports at 9:00 PM, so I suppose it will only need to get until 9:00 PM if that's easier.
Here is my query:
SELECT COUNT(*) AS Number, SUM(dblPayoutAmt) AS Amount
FROM Payouts
WHERE (dtCreated BETWEEN #startdate AND #enddate)
Don't use BETWEEN, use >= the start date and < a day past the end date:
WHERE (dtCreated >= #startdate AND dtCreated < DATEADD(day, 1, #enddate))
The reason is that BETWEEN will find up until 12:00am of the end date, but not past then.
UPDATED
For todays date, you can do this:
WHERE DATEADD(dd, 0, DATEDIFF(dd, 0, dtCreated)) = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
This will check that it has a dtCreated equal to some point today.
UPDATED
As #ScottChapman has pointed out, you can do the same thing without the conversion gymnastics by casting to the DATE type directly. This type is only available in MSSQL 2008 and later, however.
SET #StartDate = CAST(GETDATE() AS date)
SET #EndDate = DATEADD(MINUTE, -1, DATEADD(DAY, 1, #StartDate))
SELECT COUNT(*) AS Number, SUM(dblPayoutAmt) AS Amount
FROM Payouts
WHERE (dtCreated BETWEEN #startdate AND #enddate)
Some of these answers are close, but exclude times in the final minute of the day, like 11:59:30 PM. This query will include all of today:
SELECT COUNT(*) AS Number, SUM(dblPayoutAmt) AS Amount
FROM Payouts
WHERE (dtCreated >= CAST(GETDATE() as date) AND dtCreated < DATEADD(day, 1, CAST(GETDATE() as date)))
Note that this won't work in SQL Server 2005 or below, as the date type was added in SQL Server 2008.
As you're using SQL/Server 2008 you can remove any time element from a DATETIME column by converting it to DATE and select on that, E.g.
SELECT COUNT(*) AS Number, SUM(dblPayoutAmt) AS Amount
FROM Payouts
WHERE CONVERT(DATE,dtCreated) = CONVERT(DATE,GETDATE())
Very much more elegant
[EDIT]
Oh, I've just read Scott Chapman's answer, it's better because if dtCreated is indexed then the query will be more efficient.
Preceding answers also include data < 12.00 am
SELECT
COUNT(*) AS Number
, SUM(dblPayoutAmt) AS Amount
FROM
Payouts
WHERE
dtCreated >= dateadd( hour, 12, cast( cast( getdate() as date ) as datetime ))
and dtCreated < dateadd( second, -1, dateadd(day, datediff(day, -1, getdate()), 0))
set them both to SIMPLE date example: BETWEEN '2012-12-19' AND '2012-12-20' with no timestamp on them, then select the between.
In this example if you set the date for end to '2012-12-20 23:59:59.999' and then do a SELECT #enddate it returns '2012-12-21 00:00:00.000'
OR to use a function type syntax:
declare #mystart as datetime
declare #myend as datetime
set #mystart = dateadd(day,datediff(day,0,CURRENT_TIMESTAMP),0)
set #myend = dateadd(day,datediff(day,0,CURRENT_TIMESTAMP),1)
select #mystart, #myend
the #mystart here is set to ONLY the date part (time is 00:00:00.000) and the end is sent to that plus one day, so the BETWEEN syntax works.
I have a column of smalldatetime type, date
I'd like to run a query that only retrieves rows:
where date = convert(smalldatetime,GetDate())
However, this is never finding matches as it is also comparing the times.
Ie: 01-01-2010 12:23:00 != 01-01-2010 12:25:00
How can I find matches on only the date portion?
One way which will utilize the index
where date >= dateadd(dd, datediff(dd, 0, getdate()), 0)
and date < dateadd(dd, datediff(dd, 0, getdate()), +1)
See also: How Does Between Work With Dates In SQL Server?
Try:
where datediff(dd, yourdate, GetDate()) = 0
Convert your DateTime values to Date values. That will store only the date portion for you to compare.
A list of available Date and Time datatypes in MSSQL is here.
You could try:
Where CAST(FLOOR(CAST([Date] AS FLOAT)) AS DATETIME) = CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME)
This would make both dates appear as:
2010-08-05 00:00:00.000
and thus only comparing the dates ignoring the times
found this:
CAST(CONVERT (CHAR(8), GETDATE(), 112) AS smalldatetime)
from here:
reference
this sql worked for me when I added a smalldatetime field to an existing table:
SELECT testing
FROM LTCCAssessment
WHERE (testing = CAST(CONVERT(CHAR(8), GETDATE(), 112) AS smalldatetime))
where cast(CONVERT(char(10),DATETIME_FIELD_1,101) as datetime)
= cast(CONVERT(char(10),DATETIME_FIELD_2,101) as datetime)
Using SQL Server 2005 I have a field that contains a datetime value.
What I am trying to do is create 2 queries:
Compare to see if stored datetime is of the same month+year as current date
Compare to see if stored datetime is of the same year as current date
There is probably a simple solution but I keep hitting brick walls using various samples I can find, any thoughts?
Thanks in advance.
Compare the parts of the date:
WHERE YEAR( columnName ) = YEAR( getDate() )
While the other answers will work, they all suffer from the same problem: they apply a transformation to the column and therefore will never utilize an index on that column.
To search the date without a transformation, you need a couple built-in functions and some math. Example below:
--create a table to hold our example values
create table #DateSearch
(
TheDate datetime not null
)
insert into #DateSearch (TheDate)
--today
select getdate()
union all
--a month in advance
select dateadd(month, 1, getdate())
union all
--a year in advance
select dateadd(year, 1, getdate())
go
--declare variables to make things a little easier to see
declare #StartDate datetime, #EndDate datetime
--search for "same month+year as current date"
select #StartDate = dateadd(month, datediff(month, 0, getdate()), 0), #EndDate = dateadd(month, datediff(month, 0, getdate()) + 1, 0)
select #StartDate [StartDate], #EndDate [EndDate], TheDate from #DateSearch
where TheDate >= #StartDate and TheDate < #EndDate
--search for "same year as current date"
select #StartDate = dateadd(year, datediff(year, 0, getdate()), 0), #EndDate = dateadd(year, datediff(year, 0, getdate()) + 1, 0)
select #StartDate [StartDate], #EndDate [EndDate], TheDate from #DateSearch
where TheDate >= #StartDate and TheDate < #EndDate
What the statement does to avoid the transformations, is find all values greater-than or equal-to the beginning of the current time period (month or year) AND all values less-than the beginning of the next (invalid) time period. This solves our index problem and also mitigates any issues related to 3ms rounding in the DATETIME type.
SELECT * FROM atable
WHERE
YEAR( adate ) = YEAR( GETDATE() )
AND
MONTH( adate ) = MONTH( GETDATE() )
It sounds to me like DATEDIFF is exactly what you need:
-- #1 same month and year
SELECT *
FROM your_table
WHERE DATEDIFF(month, your_column, GETDATE()) = 0
-- #2 same year
SELECT *
FROM your_table
WHERE DATEDIFF(year, your_column, GETDATE()) = 0
The datepart function lets you pull the bits you need:
declare #d1 as datetime
declare #d2 as datetime
if datepart(yy, #d1) = datepart(yy, #d2) and datepart(mm, #d1) = datepart(mm, #d2) begin
print 'same'
end
You can use something like this
a)
select *
from table
where MONTH(field) = MONTH(GetDATE())
and YEAR(field) = YEAR(GetDATE())
b)
select *
from table
where YEAR(field) = YEAR(GetDATE())