I have a table of events, constantly being updated, with a datetime column.
I want to get all events that start today as well as the ones that start 8 hours into the next day.
The idea is that people don't really check in the middle of the night for events, so we list them in the day before.
To get today's I do DATEDIFF(day,eventdate,GETDATE())=0 but I havn't figured out how to do the dateadd() for my case. I either get no rows or too many.
So the wanted result is:
From 00:00 on March 9 to 8:00 on March 10. (example only)
It is better to not do any calculation on your column. Calculate the interval instead and fetch the rows that is in the interval. That way you can make use of a index on eventdate instead of doing a table scan.
select SomeColumns
from YourTable
where eventdate >= dateadd(day, datediff(day, 0, getdate()), 0) and
eventdate < dateadd(hour, 32, dateadd(day, datediff(day, 0, getdate()), 0))
You can use these to bound your query...
DECLARE #Start DateTime = CONVERT(nvarchar(10), GetDate(), 121)
DECLARE #End DateTime = DATEADD(Hour, +32, #Start)
Here's a Test Script
CREATE TABLE #Temp (Column1 DateTime)
INSERT INTO #Temp (column1) values (getdate()) -- it's 6pm now
INSERT INTO #Temp (column1) values (dateadd(hour, -24, getdate())) --6pm yesterday - outside window
INSERT INTO #Temp (column1) values (dateadd(hour, -12, getdate())) --6am today
INSERT INTO #Temp (column1) values (dateadd(hour, -5, getdate())) -- 1pm today
INSERT INTO #Temp (column1) values (dateadd(hour, +12, getdate())) -- 6am tomorrow - inside window
INSERT INTO #Temp (column1) values (dateadd(hour, +17, getdate())) -- 11am tomorrow - outside window
select * from #Temp
DECLARE #Start DateTime = CONVERT(nvarchar(10), GetDate(), 121)
DECLARE #End DateTime = DateAdd(Hour, +32, #Start)
SELECT * FROM #Temp WHERE Column1 > #Start AND Column1 < #End
SELECT
Column1, Column2
FROM
TableName
WHERE
DateColumm BETWEEN Convert(Date, GETDATE()) AND DateAdd(hh, 32, Convert(smalldatetime, Convert(Date, GETDATE())))
You can also do it this way:
select *
from yourtable
WHERE EventDate >= Convert(varchar(10), getdate(), 101)
AND EventDate < CAST(Convert(varchar(10), DateAdd(d, 1, getdate()), 101) + ' 08:00 AM' as datetime)
Then if you EventDate has the time on it, then you can convert the EventDate in the first part of your WHERE clause
select *
from yourtable
WHERE Convert(varchar(10), EventDate, 101) >= Convert(varchar(10), getdate(), 101)
AND EventDate < CAST(Convert(varchar(10), DateAdd(d, 1, getdate()), 101) + ' 08:00 AM' as datetime)
You can try something like this.
The DateAdd documention page shows all the different date parts you can use (hour, day, seconds, etc.)
DECLARE #StartTimeWindow DATETIME, #EndTimeWindow DATETIME
SET #StartTimeWindow = DATEDIFF(DAY, 0, GETDATE())
SET #EndTimeWindow = DATEADD(HOUR, 32, #StartTimeWindow)
SELECT *
FROM EventTable
WHERE EventDate >= #StartTimeWindow
AND EventDate <= #EndTimeWindow
Related
I am trying to filter records based on current date (date part only) against a column "date_sent" which is a DateTime datatype. Though this can be written in multiple ways, I want to know which method will be the most efficient. The table has 11-12 millions of records ant any given time.
Let's say the current date is 16th April 2018
SELECT *
FROM TABLE_NAME
WHERE datepart(YEAR, date_sent) = 2018
AND datepart(MONTH,date_sent) = 4
AND datepart(DAY,date_sent) = 16;
SELECT *
FROM TABLE_NAME
WHERE convert(char(8), date_sent, 112) = convert(char(8), getdate(), 112);
Any other suggestions.
I would start with:
select *
from table_name
where date_sent >= dateadd(day, datediff(day, 0, getdate()), 0) and
date_sent < dateadd(day, 1 + datediff(day, 0, getdate()), 0)
The right hand side removes the time component of the current date. The comparisons should allow Sybase to still us an index on date_sent.
EDIT:
Perhaps Sybase doesn't permit 0 as a date value. You can also do:
select *
from table_name
where date_sent >= dateadd(day, datediff(day, cast('2000-01-01' as date), getdate()), cast('2000-01-01' as date)) and
date_sent < dateadd(day, 1 + datediff(day, cast('2000-01-01' as date), getdate()), cast('2000-01-01' as date))
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 am working with SQL Server, The scenario is to find out the Same Day's Date of Previous Year as of Today's Day.
Suppose 2014-03-06 is Today Date and Day is Thursday I want to Find the Same day in Previous lies in the same week .which is 2013-03-07
can any body help?
HERE is what i Have Written:
DECLARE #DateFrom AS DATETIME
DECLARE #DateTo AS DATETIME
SET #DateFrom = '2014-01-01'
SET #DateTo = '2014-02-10'
DECLARE #Count AS INT
SET #Count = DATEDIFF(DAY, #DateFrom, #DateTo)
CREATE TABLE #current_year /*This Year*/
(
[Date] DATETIME ,
WeekNum INT,
[Day] VARCHAR(20),
Data INT
)
CREATE TABLE #last_year /*This Year -1*/
(
[Date] DATETIME ,
WeekNum INT,
[Day] VARCHAR(20),
Data INT
)
WHILE ( #Count > 0 )
BEGIN
INSERT INTO #current_year
VALUES ( CONVERT(VARCHAR(10), #DateFrom, 101),
DATEPART(week,#DateFrom),
DATENAME(weekday, #DateFrom),#Count)
INSERT INTO #last_year
VALUES ( CONVERT(VARCHAR(10), DATEADD(YEAR, -1, #DateFrom), 101),
DATEPART(week,DATEADD(YEAR,1,#DateFrom)),
DATENAME(weekday, DATEADD(YEAR, -1, #DateFrom)),#Count)
SET #DateFrom = DATEADD(day, 1, #DateFrom)
SET #Count = #Count - 1
END
SELECT * from #current_year
SELECT * from #last_year
SELECT CONVERT(varchar(10),#current_year.[Date],111) AS CYDate,
--ISNULL(CONVERT(varchar(10),#last_year.[Date],111) ,/*CONVERT(varchar(10),DateAdd(dd, 1, DATEADD(yy, -1, #current_year.Date)),111)*/) AS LYDate
--CONVERT(varchar(10),#last_year.[Date],111) AS LYDate
Coalesce(CONVERT(varchar(10),#last_year.[Date],111) ,DateAdd(dd, 1, DATEADD(yy, -1, #current_year.Date))) AS LYDate,
#current_year.Data AS CD,
#last_year.Data AS LD
FROM #current_year
--LEFT JOIN #last_year ON #last_year.WeekNum = #current_year.WeekNum
-- AND #last_year.[Day] = #current_year.[Day]
Left JOIN #last_year ON #last_year.WeekNum = DatePart(wk, GETDATE())
DROP TABLE #current_year
DROP TABLE #last_year
Here is the Output:
Here is the output after adding your solution, now in left join it excludes (NULL) data of previous year
Basically you need to find difference in days between same dates in this and previous years, then understand "day difference" by mod 7, and sum it with date in previous year:
DECLARE #now DATETIME
SET #now = '2014-03-06'
SELECT CAST (DATEADD(YEAR, -1, #now) + (CAST (#now as INT) - CAST (DATEADD(YEAR, -1, #now) AS INT)) % 7 AS DATE)
Returns
2013-03-07
Try
DECLARE #now Date
SET #now = '2014-06-03'
SELECT DATEADD(week, -52, #now)
SELECT DateName(dw, DATEADD(yy, -1, GETDATE()))
gives Wednesday
SELECT DateName(dw, DateAdd(dd, 1, DATEADD(yy, -1, GETDATE())))
gives Thursday
edit:
SELECT DateAdd(dd, 1, DATEADD(yy, -1, GETDATE()))
gives '2013-03-07 17:30:16.590'
you need to cast the date as per you requirement..
update:
change this part with,
Left JOIN #last_year ON #last_year.WeekNum = DatePart(wk, GETDATE())
in your case:
Left JOIN #last_year ON DatePart(wk, #last_year.[Date]) = DatePart(wk, #current_year.[Date])
update 2:
Left JOIN #last_year ON (MONTH(#last_year.[Date])=MONTH(#current_year.[Date]) and Day(#last_year.[Date])=Day(#current_year.[Date]))
Output:
or
output:
Left JOIN #last_year ON (#last_year.WeekNum = #current_year.WeekNum and #last_year.[Day] = #current_year.[Day])
choose which ever is your required output.
DECLARE #Date DATE = '2014-03-06'
SELECT DATEADD(WEEK,-52,#Date)
Retrun value :
2013-03-07
I'm having a hard time doing this query.
I want to compare dates in my query, dates from my DB are in this format:
(MM/DD/YYYY HH:MM:SS AM)
I want to compare this date with tomorrow's day, today plus one.
My questions are:
How do I declare tomorrow's date in sql server?
How would you compare these two dates?
Thank you!! =D
EDIT : DATES in DB are VarChar =S
declare tomorrow's date : DATEADD(dd,1,getdate())
compare dates :
WHERE column >= CONVERT(datetime, CONVERT(varchar, DATEADD(day, 1, GETDATE()), 102))
AND column < CONVERT(datetime, CONVERT(varchar, DATEADD(day, 2, GETDATE()), 102))
Assumes datetime datatype for columns
WHERE
MyCol >= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 1)
AND
MyCol < DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 2)
This (yyyy-mm-dd) removes the time component to test of MyCol is tomorrow
2009-10-06 00:00:00 <= MyCol < 2009-10-07 00:00:00
You don't strip time from MyCol: this will affect performance and disallow index usage etc
Efficiency of remove time from datetime question, which is why I used this format and avoid varchar conversions...
Edit:
Avoiding implicit conversions and string matching
10/06/2009 <= MyCol < 10/07/2009
WHERE
MyCol >= CONVERT(char(10), DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 1), 101)
AND
MyCol < CONVERT(char(10), DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 2), 101)
Of course, it'll fail at the end of December...
I would think your dates are most likely to be in SQL Server's datetime datatype, and that the format you give is just the default string representation.
Typically, I use something like:
SELECT *
FROM tbl
WHERE datecol = CONVERT(datetime, CONVERT(varchar, DATEADD(day, 1, GETDATE()), 101))
However, if your datetimes include a time piece, you need to use something like this:
SELECT *
FROM tbl
WHERE datecol >= CONVERT(datetime, CONVERT(varchar, DATEADD(day, 1, GETDATE()), 101))
AND datecol < CONVERT(datetime, CONVERT(varchar, DATEADD(day, 2, GETDATE()), 101))
There are other date arithmetic tricks you can use. There are plenty here on SO if you look for SQL dates
SQL Server allows you to declare variables
DECLARE #TomorrowsDate DateTime
And you can set it to the current date and time
SET #TomorrowsDate = DATEADD (Day, 0, GETDATE())
For tomorrow's date (without time)
SET #TomorrowsDate = DATEADD (Day, 1, CONVERT (VARCHAR, GETDATE(), 101))
To use it in a query with a column without declaring a variable
SELECT Column1, Column2
FROM YourTableName
WHERE DateColumn BETWEEN DATEADD (Day, 0, CONVERT (VARCHAR, GETDATE(), 101))
AND DATEADD (Day, 1, CONVERT (VARCHAR, GETDATE(), 101))
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())