If you want to avoid iterating (for instance, if you need this data in a view), you can use the following technique:
;WITH w(weeknumber) AS
(SELECT 0
UNION SELECT 1
UNION SELECT 2
UNION SELECT 3
UNION SELECT 4
UNION SELECT 5
UNION SELECT 6
UNION SELECT 7),
f(firstdayofweek) AS
(SELECT DATEADD(ww,DATEDIFF(ww,0,GETDATE()),0)),
o(offsetweekdate) AS
(SELECT DATEADD(ww,w.weeknumber,f.firstdayofweek) FROM w,f)
SELECT
DATEADD(d,0,o.offsetweekdate) AS firstdayofweek,
DATEADD(d,6,o.offsetweekdate) AS lastdayofweek
FROM o
Here, w
generates a list of numbers from 0 to 7,f
finds the first day of the week, and o
combines these two to give the start and end dates of the week for the next 8 weeks.
The disadvantage of this is that to increase the number of weeks projected forwards, you'd need to add an extra line to the definition of w. This is because there is no built-in way to generate a range of values using TSQL without using loops.
Jeff Moden posted a very helpful range function elsewhere on StackOverflow which I like to use in these kind of scenarios.
CREATE FUNCTION [dbo].[Range](@startvalue integer,@endvalue integer)
RETURNS TABLE
AS
RETURN(
WITH E00(N) AS (SELECT 1 UNION ALL SELECT 1),
E02(N) AS (SELECT 1 FROM E00 a, E00 b),
E04(N) AS (SELECT 1 FROM E02 a, E02 b),
E08(N) AS (SELECT 1 FROM E04 a, E04 b),
E16(N) AS (SELECT 1 FROM E08 a, E08 b),
E32(N) AS (SELECT 1 FROM E16 a, E16 b),
cteTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY N) FROM E32)
SELECT TOP (@endvalue-@startvalue+1) (N+@startvalue-1) AS Number
FROM cteTally
WHERE N <= (@endvalue-@startvalue+1))
This allows you to generate a range using a simple SELECT Number FROM RANGE(0,10)
. Once you've defined this function, the original code can be reduced to the following:
;WITH w(weeknumber) AS
(SELECT Number FROM Range(0,7)),
f(firstdayofweek) AS
(SELECT DATEADD(ww,DATEDIFF(ww,0,GETDATE()),0)),
o(offsetweekdate) AS
(SELECT DATEADD(ww,w.weeknumber,f.firstdayofweek) FROM w,f)
SELECT
DATEADD(d,0,o.offsetweekdate) AS firstdayofweek,
DATEADD(d,6,o.offsetweekdate) AS lastdayofweek
FROM o
It would then be a simple change to extend this to take a parameter for the number of weeks to project forwards.