How to write a sql statement that always returns data from last Monday to the last Sunday? Any guidance is appreciated.
Thanks.
You did not specify which SQL dialect, so I will answer for T-SQL, which is what I know best, and you've used the tsql
tag.
In T-SQL, use the DATEPART function to find the day of the week. When you know the current day of the week, you can get the date of the most recent Sunday and the Monday before it.
In a stored procedure, it's easier—at least, more readable and easier to maintain, in my opinion—to calculate the values for the most recent Sunday and the preceding Monday and store the values in variables. Then those variables can be used in calculations later in the procedure.
CREATE PROCEDURE SomeProcedure
AS
DECLARE @CurrentDayOfWeek int, @LastSunday date, @LastMonday date
SET @CurrentWeekday = DATEPART(weekday, GETDATE())
-- Count backwards from today to get to the most recent Sunday.
-- (@CurrentWeekday % 7) - 1 will give the number of days since Sunday;
-- -1 negates for subtraction.
SET @LastSunday = DATEADD(day, -1 * (( @CurrentWeekday % 7) - 1), GETDATE())
-- Preceding Monday is obviously six days before last Sunday.
SET @LastMonday = DATEADD(day, -6, @LastSunday)
SELECT ReportColumn1, ReportColumn2
FROM ReportTable
WHERE DateColumn BETWEEN @LastMonday AND @LastSunday
If you need to be able to do the calculation in a SELECT statement or a view, it's trivial now that we've worked out the steps, though the query itself is a little messier:
SELECT ReportColumn1, ReportColumn2
FROM ReportTable
WHERE DateColumn
BETWEEN
(
-- Last Monday is six days before...
DATEADD(day, -6,
-- ... last Sunday.
DATEADD(day, -1 * (( DATEPART(weekday, GETDATE()) % 7) - 1), GETDATE())
)
)
AND
(
-- Last Sunday has to be calculated again each time it is used inline.
DATEADD(day, -1 * (( DATEPART(weekday, GETDATE()) % 7) - 1), GETDATE())
)
The parentheses I added are not necessary, but are only there to help you see how the WHERE clause is built.
Finally, note that these use the SQL 2008 date
data type; for the datetime
data type, you may need to perform your own conversion/truncation to compare whole dates instead of date-plus-time values.