SQL specific time with a moving date - sql

I'm using MS SQL and I'd like to have a query that is basically
SELECT * FROM Data Where TimeStamp <= 06:30:00 Last Saturday
Anyone have anything functional to achieve this?

You can get that time for last Saturday using 30 minutes and 6*60 for minutes in 6 hours (you can get this a few ways but I hard coded it using that:
DATEADD(MINUTE,(30 + (6 * 60) ), DATEADD(WEEK, DATEDIFF(WEEK, -1, CURRENT_TIMESTAMP), -2))
Then you can use that in the where clause:
SELECT
*
FROM dbo.Data AS d
WHERE
d.TimeStamp <= DATEADD(MINUTE,(30 + (6 * 60) ), DATEADD(WEEK, DATEDIFF(WEEK, -1, CURRENT_TIMESTAMP), -2))
UPDATE: TLDR; Break this down using a sample query: (hopefully it helps)
DECLARE #MyDatetime AS DATETIME = '2021-09-12 03:02:05.257' --CURRENT_TIMESTAMP;
SELECT
#MyDatetime AS FromWhen,
/* all these are The int difference between the startdate and enddate, expressed in the boundary set by datepart (WEEK)) */
DATEDIFF(WEEK, 0, #MyDatetime) AS MyWeek0,
DATEDIFF(WEEK, -1, #MyDatetime) AS MyWeek1,
DATEDIFF(WEEK, -2, #MyDatetime) AS MyWeek2,
DATEDIFF(WEEK, -3, #MyDatetime) AS MyWeek3,
DATEDIFF(WEEK, -4, #MyDatetime) AS MyWeek4,
DATEDIFF(WEEK, -5, #MyDatetime) AS MyWeek5,
DATEDIFF(WEEK, -6, #MyDatetime) AS MyWeek6,
DATEDIFF(WEEK, -7, #MyDatetime) AS MyWeek7,
DATEDIFF(WEEK, -8, #MyDatetime) AS MyWeek8,
DATEDIFF(WEEK, -1, #MyDatetime) AS AWeekBack, -- get the week a week from RightNow DATEDIFF ( datepart , startdate , enddate )
DATEADD(WEEK, DATEDIFF(WEEK, -1, #MyDatetime), -2) AS Saturday0000, -- Get the Saturday date from that (-2 is saturday, -1 sunday, ...-7 monday)
DATEADD(MINUTE,(30 + (6 * 60) ), DATEADD(WEEK, DATEDIFF(WEEK, -1, #MyDatetime), -2)) AS Saturday0630 -- now add the minutes for 6:30 AM to that saturday date
Values for a given set from that query:
FromWhen MyWeek0 MyWeek1 MyWeek2 MyWeek3 MyWeek4 MyWeek5 MyWeek6 MyWeek7 MyWeek8 AWeekBack Saturday0000 Saturday0630
2021-09-12 03:02:05.257 6350 6350 6351 6351 6351 6351 6351 6351 6351 6350 2021-09-11 00:00:00.000 2021-09-11 06:30:00.000
Broken down:
Go back a week (-1) from NOW
DATEDIFF always uses Sunday as the first day of the week to ensure the function operates in a deterministic way this -2 is Saturday.
DATEDIFF(WEEK, -1, CURRENT_TIMESTAMP)
For example this is one query I use often get get those few thousand rows from a 120 second range on a given DATETIME column:
SELECT *
FROM SomeTable AS st
WHERE
st.DateColumn >= DATEADD(SECOND, -60, #SomeDateTime)
AND st.DateColumn < DATEADD(SECOND, 60, #SomeDateTime)

With a calendar table, this is quite logical. Get me the highest row from the table that is a Saturday before today.
DECLARE #d smalldatetime;
SELECT #d = DATEADD(MINUTE, 390, MAX(TheDate))
FROM dbo.CalendarTable
WHERE TheDayName = 'Saturday'
AND TheDate < CONVERT(date, GETDATE());
SELECT ... FROM dbo.Data WHERE [TimeStamp]/*shudder*/ <= #d;
Without a calendar table, you can do this in a slightly less intuitive way, by picking a known Saturday in the past, and adding the number of weeks that have passed since that date, less 1:
DECLARE #KnownSat smalldatetime = '20110101';
SELECT #d = DATEADD(MINUTE, 390, DATEADD
(
WEEK,
DATEDIFF(WEEK, #KnownSat, GETDATE()) - 1,
#KnownSat
));
SELECT ... FROM dbo.Data WHERE [TimeStamp]/*shudder*/ <= #d;
Note that both solutions will return the previous Saturday when run on a Saturday.

Related

SQL fetch data for the present year until previous week friday

Am trying to fetch data in SQL until previous week Friday for the present year from the datetime field fetchDate
I tried something like this but it fetches until today
(year(fetchDate) = year(GETDATE()) and month(fetchDate) <= month(GETDATE()) and day(fetchDate) <= day(GETDATE()))
whereas
(year(fetchDate) = year(GETDATE()) and month(fetchDate) <= month(GETDATE()) and day(fetchDate) <= day(DATEADD(wk,DATEDIFF(wk,7,GETDATE()),4)))
brings me data only for the present month of the year until last week.
I believe what you need is the following:
WHERE YEAR(fetchDate) = YEAR(CURDATE())
AND fetchDate < DATE_SUB(NOW(), INTERVAL ((7 + WEEKDAY(DATE_SUB(NOW(), INTERVAL 1 WEEK)) - 4) % 7) DAY)
We get how many days ago last week's Friday was with:
((7 + WEEKDAY(DATE_SUB(NOW(), INTERVAL 1 WEEK)) - 4) % 7)
I would rather go for the following solution as it is sargable. Inside the WHERE predicate we are not wrapping the fetchdate into a function (e.g. YEAR(Fetchdate)), the query optimizer could use existing indexes and does not have to scan the whole table. Especially for BI workloads where this query is common, it is extremely important to optimize for that a lot of records are queried. It comes at the cost of little less readability
declare #tab table
(
fetchdate datetime
)
insert into #tab
values ('2019-01-01'),('2019-03-15'),('2018-12-31'),('2019-03-16')
SELECT
*,
case when datepart(weekday, getdate()) >5 then
DATEADD(DAY, +4, DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()), 0))
else DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()), 0)) end as TestLastFriday,
DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0) as TestFirstDayOfYear
FROM #tab
where
fetchdate <= case when datepart(weekday, getdate()) >5 then DATEADD(DAY, +4, DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()), 0))
else DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()), 0)) end and
fetchdate >= DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0)

Using DATEADD and DATEDIFF truncates the time

I am using the following to get to get the 1st day of next month with time:
select DATEADD(m, DATEDIFF(m, -1, getdate()), 0)
But the output is:
2018-12-01 00:00:00.000
And the expected result is:
2018-12-01 11:53:30.677
I have tried various approaches but not able to get required output. I am using SQL Server 2008.
You can add two datetime values, one for the date and the other for the time:
select DATEADD(month, DATEDIFF(month, -1, getdate()), 0) + cast(cast(getdate() as time) as datetime)
I am guessing that you want the time value from the current time.
Subtract DAY(#date) - 1 days from #date to get first day of that month including time. Then add one month:
SELECT DATEADD(MONTH, 1, DATEADD(DAY, -DAY(GETDATE()) + 1, GETDATE()))
-- 2018-12-01 04:52:33.403
try like below
select DATEADD(m, DATEDIFF(m, -1, getdate()), 0)+ convert(DATETIME,'11:53:30.677')
in case of current time it would be like below
select DATEADD(m, DATEDIFF(m, -1, getdate()), 0)+ convert(datetime, convert(time,getdate()))

Last 5 weeks prior to the last week in SQL

I want to take the last 5 weeks prior to the week before the current week. Today is Oct 4, 2017 so I want date range to be between Aug 21-Sep 24. This is the code I'm using, but it doesn't work for some reason:
DATEADD(week, -5, GETDATE()) and DATEADD(week, -1, GETDATE())
I also tried DATEADD(week, -6, GETDATE()) and DATEADD(week, -2, GETDATE()) but no change happens, so weird.
Can anyone help me please. It's sql query in SQL 2012.
WHERE hire_date between DATEADD(week, -6, GETDATE()) and DATEADD(week, -2, GETDATE())
Look at each of the expressions individually. Use Management Studio (or similar) to run just this:
SELECT DATEADD(week, -1, GETDATE())
And you'll see something like this (relative to the time when you run it):
2017-09-27 15:05:39.453
That's exactly one week ago, which was still a Wednesday. You want Sunday, the start of that week. So now do this:
SELECT DATEADD(week, DATEDIFF(week, 0, GETDATE()) -1, 0)
Which gives you this result:
2017-09-25 00:00:00.000
Closer. It works by taking day 0 and adding one less than the number of weeks that have passed since the week from your target date. You're adding whole weeks, and so you end up with a predictable whole-week start. You get the 25th (Monday) instead of the 24th because day 0 (Jan 1 1900) happened to be a Monday. But it's reliably a Monday, and easy enough now to account for the one more day:
SELECT DATEADD(DAY, -1, DATEADD(week, DATEDIFF(week, 0, GETDATE()) -1, 0))
And now we have a date you can use, from an expression that will consistently get it right:
2017-09-24 00:00:00.000
Sort of. You do need to carefully test how this behaves if run on Sunday or Monday, especially as Sql Server has a configurable start-of-week value. You may find you've crossed one fewer or greater week boundaries than you expect and end up with weird off-by-one errors. But even if that happens, this approach puts you on the path you need to walk.
For the other end, just change the number of weeks:
SELECT DATEADD(week, DATEDIFF(week, 0, GETDATE()) -6, 0)
To get this:
2017-08-21 00:00:00.000
Since the question asked for the Monday instead of Sunday we get skip the extra DATEADD() from before.
Now put it all together like so:
WHERE hire_date between
DATEADD(week, DATEDIFF(week, 0, GETDATE()) -6, 0)
AND
DATEADD(DAY, -1, DATEADD(week, DATEDIFF(week, 0, GETDATE()) -1, 0))
From what you're saying I think you need the first day of the earliest week to the last day of the latest week. To achieve this, you can do this:
WHERE hire_date between DATEADD(week, -6, DATEADD(WEEK, DATEDIFF(wk,0,GETDATE()), 0))
and DATEADD(week, -2, DATEADD(WEEK, DATEDIFF(wk,5,GETDATE()), 6))
DATEADD(week, -5, GETDATE()) substracts 30 days. You are going to have to do some manual DATEADD to get it to the beginning of the week, which is what it sounds like you're trying to do.
DECLARE #date datetime = GETDATE()
DECLARE #dw nvarchar = DATENAME(dw, #date)
IF #dw = 'Monday' SET #date = DATEADD(day, -1, #date)
ELSE IF #dw = 'Tuesday' SET #date = DATEADD(day, -2, #date)
....
WHERE hire_date between DATEADD(week, -6, #date) and DATEADD(week, -2, #date)
This way, you can set the beginning of the week yourself without having to be dependent on system culture.

How to get the date from last Sunday to Saturday

I will entries in my table which will have date with data like this:
Date Value
4-20-2014 45
4-21-2014 15
4-22-2014 35
...
4-30-2014 109
I will be executing my Stored Procedure every Sunday which means I would like to get the row with Date from previous Sunday until Yesterday (Saturday).
I have the following query which will get from Previous Sunday to Previous Saturday which I think is wrong so I modified it as the following:
INSERT INTO [database].[dbo].[table]
SELECT (WEEKENDING DATE) AS [Date], SUM([ORDERS]) AS Orders, SUM([B ORDERS]) AS bOrders, SUM([RESULT]) AS Results
FROM [database].[dbo].[origtable]
WHERE
[Date] >= "PREVIOUS SUNDAY DATE"
AND
[Date] <= "SATURDAY DATE (YESTERDAY)"
I would like to get some help with the following line:
[Date] >= "PREVIOUS SUNDAY DATE"
AND
[Date] <= "SATURDAY DATE (YESTERDAY)"
So if I run the SP on 5/4/2014, it will grab between Sunday (4/27/2014) to Saturday (5/3/2014)
Will this work:
INSERT INTO [Database].[dbo].[table]
SELECT
CONVERT(VARCHAR(10), GETDATE(), 101) AS [Date],
SUM([EMR ORDERS]) AS LastWeekEMROrders,
SUM([ACCESSIONED LAB ORDERS]) AS LastWeekAccLabOrders,
SUM([LAB_RESULT]) AS LastWeekLabResults
FROM [database].[dbo].[origtable]
WHERE
[Date] >= DATEADD(day, -((DATEPART(dw, GETDATE()) + ##DATEFIRST) % 7) - 6,
DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0)) --PREVIOUS SUNDAY
AND
[Date] <= DATEADD(day, -(DATEPART(dw, GETDATE()) + ##DATEFIRST) % 7,
DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0)) --PREVIOUS SATURDAY
If I have the following query and execute it on 5/4/2014:
set #startdate = DATEADD(wk, DATEDIFF(wk, 0, getdate()), -2) --for sunday
set #enddate = DATEADD(wk, -1, DATEADD(wk, DATEDIFF(wk, 0,getdate()), -1))-- for saturday
What will be the sunday's and saturday's date?
Try the following modified query:
EDIT:
The query has been further modified to not use DATEFROMPARTS.
INSERT INTO [Database].[dbo].[table]
SELECT CONVERT(VARCHAR(10), GETDATE(), 101) AS [Date], SUM([EMR ORDERS]) AS LastWeekEMROrders, SUM([ACCESSIONED LAB ORDERS]) AS LastWeekAccLabOrders, SUM([LAB_RESULT]) AS LastWeekLabResults
FROM [database].[dbo].[origtable]
WHERE
[Date] >= DATEADD(d, -8, DATEADD(dd, DATEDIFF(dd,0, current_timestamp), 0)) --PREVIOUS SUNDAY
AND
[Date] <= DATEADD(d, -1, DATEADD(dd, DATEDIFF(dd,0, current_timestamp), 0)) --PREVIOUS SATURDAY;
References:
Date and Time Data Types and Functions (Transact-SQL) on TechNet
Related SO question

How to get last week date range based on current date in sql?

I have this code in crystal reports that gives me last week date range based on the current date.
First day of the week:
If DayOfWeek(currentdate) = 2 Then
currentdate
Else If DayOfWeek(currentdate) = 3 Then
dateadd ("d",-1,currentdate)
Else If DayOfWeek(currentdate) = 4 Then
dateadd ("d",-2,currentdate)
Else If DayOfWeek(currentdate) = 5 Then
dateadd ("d",-3,currentdate)
Else If DayOfWeek(currentdate) = 6 Then
dateadd ("d",-4,currentdate)
Else If DayOfWeek(currentdate) = 7 Then
dateadd ("d",-5,currentdate)
Else If DayOfWeek(currentdate) = 1 Then
dateadd ("d",-6,currentdate)
Last day of week:
If DayOfWeek(currentdate) = 2 Then
dateadd ("d",+6,currentdate)
Else If DayOfWeek(currentdate) = 3 Then
dateadd ("d",+5,currentdate)
Else If DayOfWeek(currentdate) = 4 Then
dateadd ("d",+4,currentdate)
Else If DayOfWeek(currentdate) = 5 Then
dateadd ("d",+3,currentdate)
Else If DayOfWeek(currentdate) = 6 Then
dateadd ("d",+2,currentdate)
Else If DayOfWeek(currentdate) = 7 Then
dateadd ("d",+1,currentdate)
Else If DayOfWeek(currentdate) = 1 then currentdate
How can I do the same in SQL using 2 variables to storage Monday(startdate) and Sunday(enddate)?
I found this select datepart(dw,getdate()) --6 in this site, but I do not know how to use it.
I generated some spaced out dates in the parms CTE then SELECT the CurrentDate from parms, the Sunday of the week prior to CurrentDate and the Saturday of the week prior to CurrentDate. I'm assuming that you want the dtate range to be Sunday - Saturday.
Sunday - Saturday Ranges
;WITH parms (CurrentDate) AS (
SELECT DATEADD(dd, -14, CURRENT_TIMESTAMP) UNION
SELECT DATEADD(dd, -6, CURRENT_TIMESTAMP) UNION
SELECT DATEADD(dd, 2, CURRENT_TIMESTAMP) UNION
SELECT DATEADD(dd, 8, CURRENT_TIMESTAMP) UNION
SELECT DATEADD(dd, 15, CURRENT_TIMESTAMP) UNION
SELECT DATEADD(dd, 20, CURRENT_TIMESTAMP)
)
SELECT CurrentDate
, LastWeekSunday = DATEADD(dd, -1, DATEADD(ww, DATEDIFF(ww, 0, CurrentDate) - 1, 0))
, LastWeekSaturday = DATEADD(dd, 5, DATEADD(ww, DATEDIFF(ww, 0, CurrentDate) - 1, 0))
FROM parms
Monday to Sunday Ranges
;WITH parms (CurrentDate) AS (
SELECT DATEADD(dd, -14, CURRENT_TIMESTAMP) UNION
SELECT DATEADD(dd, -6, CURRENT_TIMESTAMP) UNION
SELECT DATEADD(dd, 2, CURRENT_TIMESTAMP) UNION
SELECT DATEADD(dd, 8, CURRENT_TIMESTAMP) UNION
SELECT DATEADD(dd, 15, CURRENT_TIMESTAMP) UNION
SELECT DATEADD(dd, 20, CURRENT_TIMESTAMP)
)
SELECT CurrentDate
, LastWeekMonday = DATEADD(dd, 0, DATEADD(ww, DATEDIFF(ww, 0, DATEADD(dd, -1, CurrentDate)) - 1, 0))
, LastWeekSunday = DATEADD(dd, 6, DATEADD(ww, DATEDIFF(ww, 0, DATEADD(dd, -1, CurrentDate)) - 1, 0))
FROM parms
If you just want the prior week's Monday to the prior week's Sunday from today rather than from a column of dates you can use this
SELECT CURRENT_TIMESTAMP
, LastWeekSunday = DATEADD(dd, 0, DATEADD(ww, DATEDIFF(ww, 0, DATEADD(dd, -1, CURRENT_TIMESTAMP)) - 1, 0))
, LastWeekSaturday = DATEADD(dd, 6, DATEADD(ww, DATEDIFF(ww, 0, DATEADD(dd, -1, CURRENT_TIMESTAMP)) - 1, 0))
This solution is tested and works. I am getting the previous week's Monday and Sunday as upper and lower bounds.
SELECT
-- 17530101 or 1753-01-01 is the minimum date in SQL Server
DATEADD(dd, ((DATEDIFF(dd, '17530101', GETDATE()) / 7) * 7) - 7, '17530101') AS [LowerLimit], -- Last Week's Monday
DATEADD(dd, ((DATEDIFF(dd, '17530101', GETDATE()) / 7) * 7) - 1, '17530101') AS [UpperLimit] -- Last Week's Sunday.
Which can be used like this in a real world query:
SELECT
*
FROM
SomeTable
WHERE
SomeTable.[Date] >= DATEADD(dd, ((DATEDIFF(dd, '17530101', GETDATE()) / 7) * 7) - 7, '17530101') AND
SomeTable.[Date] <= DATEADD(dd, ((DATEDIFF(dd, '17530101', GETDATE()) / 7) * 7) - 1, '17530101')
Here are some tests:
1. Leap Year
Current Date: 2016-02-29 00:00:00.000
Results:
LowerLimit UpperLimit
2016-02-22 00:00:00.000 2016-02-28 00:00:00.000
2. Last Week was in different year
Current Date: 2016-01-06 00:00:00.000
LowerLimit UpperLimit
2015-12-28 00:00:00.000 2016-01-03 00:00:00.000
3. Lower limit in previous month and upper limit in current month
Current Date: 2016-05-04 00:00:00.000
LowerLimit UpperLimit
2016-04-25 00:00:00.000 2016-05-01 00:00:00.000
4. Current Date is Sunday
Current Date: 2016-05-08 00:00:00.000
LowerLimit UpperLimit
2016-04-25 00:00:00.000 2016-05-01 00:00:00.000
Bill's code worked well, but I needed to make a slight edit if I wanted to get last Sunday to Saturday based on today's date.
select CURRENT_TIMESTAMP,
LastWeekSunday = DATEADD(dd, -1, DATEADD(ww, DATEDIFF(ww, 0, DATEADD(dd, -1, CURRENT_TIMESTAMP)) - (case datename(weekday,CURRENT_TIMESTAMP) when 'Sunday' then 0 else 1 end), 0)),
LastWeekSaturday = DATEADD(dd, 5, DATEADD(ww, DATEDIFF(ww, 0, DATEADD(dd, -1, CURRENT_TIMESTAMP)) - (case datename(weekday,CURRENT_TIMESTAMP) when 'Sunday' then 0 else 1 end), 0))
Rgds - Matt
For everything date and date interval related, I'd almost always recommend using a calendar table. A table with columns representing date, week, month, year, day of week, hiliday, weekand, etc, prepopulated as needed and indexed on every column. It's only 365 rows per year.
select min(date), max(date)
from calendar
where week = datepart(week, getdate() - 7)
and year = datepart(year, getdate() - 7)
A shortened version concise syntax
last week, in my vision is the prev adjacent week, so if Im doing report during the week days, I want to receive dates of previous adjacent week Monday to Sunday.
prev Monday is DATE_ADD(CURDATE(), INTERVAL -(5 + dayofweek(CURDATE())) DAY)
prev Sunday is DATE_ADD(CURDATE(), INTERVAL -(dayofweek(CURDATE()) - 1) DAY)
then to take the report from the table need just to integrate those two in SELECT statement
select * from XXX where DateCol between DATE_ADD(CURDATE(), INTERVAL -(5 + dayofweek(CURDATE())) DAY) and DATE_ADD(CURDATE(), INTERVAL -(dayofweek(CURDATE()) - 1) DAY) order by DateCol
I'm late to this party, but wanted to add a simpler way that works for me in SQL Server (when the other examples did not).
select * from table
-- this is for the previous week:
where (datefield >= DATEADD(dd, -1, DATEADD(ww, DATEDIFF(ww, 0, GETDATE()) - 1, 0)) and datefield < DATEADD(dd, 6, DATEADD(ww, DATEDIFF(ww, 0, GETDATE()) - 1, 0)))
-- alternatively, this is for a rolling 7 days:
and DATEDIFF(day, datefield, GETDATE()) between 0 and 7