SQL Middle of the Month - sql

I know you can set #Date to 01/01/2001 as beginning of the month.
and then call dates that are first of every month, for example:
01/01/2001
01/02/2001
01/03/2001
but how would I please if possible is always find the date in the middle of the month? I would use 15th, but issue you have is with February
I need to make analysis of sum of sales mid month
any ideas please team

you can use this formula
DECLARE #Date DATE ='20180201'
SELECT DATEADD(DAY, (DAY(EOMONTH(#Date)) / 2) - 1, #Date)

Solution:
Get the count of the days in the month and calculate the "middle" day. In the next example the count of the days (28, 29, 30 or 31) is divided by an integer divisor (2), so the result will be an integer that has any fractional part truncated. Choose your preferred method.
DECLARE #date date
SET #date = DATEFROMPARTS(2020, 2, 1)
-- 15 is the half of the month with 30 and 31 days, 14 for months with 28, 29 days
SELECT DATEDIFF(d, #date, DATEADD(month, 1, #date)) / 2
-- 16 is the half of the month with 31 days, 15 for months with 29, 30 days, 14 for month with 28 days
SELECT (DATEDIFF(d, #date, DATEADD(month, 1, #date)) + 1) / 2
Example:
WITH Months AS
(
SELECT SomeDate = DATEFROMPARTS(2018, 1, 1)
UNION ALL
SELECT DATEADD(month, 1, SomeDate)
FROM Months
WHERE DATEPART(month, SomeDate) < 12
)
SELECT
SomeDate AS FirstDate,
DATEADD(d, -1, DATEADD(month, 1, SomeDate)) AS LastDate,
DATEDIFF(d, SomeDate, DATEADD(month, 1, SomeDate)) AS DaysBetween,
DATEDIFF(d, SomeDate, DATEADD(month, 1, SomeDate)) / 2 AS HalfOfMonth1,
(DATEDIFF(d, SomeDate, DATEADD(month, 1, SomeDate)) + 1) / 2 AS HalfOfMonth2
FROM Months
Output:
FirstDate LastDate DaysBetween HalfOfMonth1 HalfOfMonth2
01/01/2018 31/01/2018 31 15 16
01/02/2018 28/02/2018 28 14 14
01/03/2018 31/03/2018 31 15 16
01/04/2018 30/04/2018 30 15 15
01/05/2018 31/05/2018 31 15 16
01/06/2018 30/06/2018 30 15 15
01/07/2018 31/07/2018 31 15 16
01/08/2018 31/08/2018 31 15 16
01/09/2018 30/09/2018 30 15 15
01/10/2018 31/10/2018 31 15 16
01/11/2018 30/11/2018 30 15 15
01/12/2018 31/12/2018 31 15 16

i have tried the following
SELECT DATEADD(dd, (datediff(DD, DATEADD(m, DATEDIFF(m, 0, GETDATE()), - 1), eomonth(getdate())) / 2), DATEADD(m, DATEDIFF(m, 0, GETDATE()), - 1)),
CEILING((datediff(DD, DATEADD(m, DATEDIFF(m, 0, GETDATE()), - 1), eomonth(getdate())) / 2.00))
An update to the answer
DECLARE #Date DATE ='2018-10-01'---'20180201'
SELECT DATEADD(DAY, CEILING((DAY(EOMONTH(#Date)) / 2.00)) - 1, #Date)

Here is a query that get start date of month and end date of month by using datediff you can find the number of day to add and subtract
Set #tdate = '02/10/2018';
Select DATEFROMPARTS(YEAR(#tdate),MONTH(#tdate),1) as startdate , dateadd(day,-1,DATEFROMPARTS(YEAR(#tdate),MONTH(#tdate)+1,1)) as enddate
Regards

Related

Displaying start date of week in SQL

I have a SQL query that to return the number of items per week. I have a query that returns so far this:
Number of Items | Week Number
-------------------------------
100 | 18
80 | 19
120 | 20
And would like to return the following:
Number of Items | Week Beginning
-------------------------------
100 | 1st May 2017
80 | 8th May 2017
120 | 15th May 2017
What I have so far is:
SELECT COUNT(*) AS 'Number of Items', DATEPART(WEEK, Date) FROM table
where DATEPART(Year, Date) = '2017' and DATEPART(MONTH, Date) = 5
group by DATEPART(WEEK, Date)
You are talking about the 1st day of the current week:
example: select FORMAT(dateadd(ww,datediff(ww,0,getdate()),0),'dd MMM yyyy')--if you are using SQL 2012+
answer:
SELECT COUNT(*) AS 'Number of Items', FORMAT(dateadd(ww,datediff(ww,0,date_column),0),'dd MMM yyyy')
FROM table
where DATEPART(Year, Date) = '2017' and DATEPART(MONTH, Date) = 5
group by DATEPART(WEEK, Date)
As you need Monday to be the first day of the week
select DATEPART(WEEK, MyDate),DATEADD(DAY,1,(DATEADD(DAY, 1-DATEPART(WEEKDAY, MyDate), MyDate)))
from (
select '5/3/2017' MyDate
union all select '5/10/2017'
union all select '5/14/2017')A
SELECT DATEADD(DAY, DATEDIFF(DAY, 0, Date) /7*7, 0) AS StartDateOfWeek
check this if it solves
DECLARE #WeekNum INT
, #YearNum char(4);
SELECT #WeekNum = 20
, #YearNum = 2017
-- once you have the #WeekNum and #YearNum set, the following calculates the date range.
SELECT DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + #YearNum) + (#WeekNum-1), 6) AS StartOfWeek;
SELECT DATEADD(wk, DATEDIFF(wk, 5, '1/1/' + #YearNum) + (#WeekNum-1), 5) AS EndOfWeek;
thanks to http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=185440

Auto pickup dates from SQL Server - T-SQL

I am looking for some T-SQL code that should pick the date which is "One Year back from current date (at the same time last Sunday in the month of January)".
For example:
Current day expected result
2017-02-05 2016-01-31
2017-01-05 2015-01-25
2018-02-19 2017-01-29
2018-01-19 2016-01-31
2019-02-28 2018-01-28
Please note: The year starts from last Sunday in January
I have some T-SQL code which is being used in SQL Server 2014:
select
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(GetDate()) = 1 THEN CONVERT(VARCHAR(4), GetDate(), 112) - 1 ELSE CONVERT(VARCHAR(4), GetDate(), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)
The above code picks the date for current year's (last Sunday in January month). But I want T-SQL code to pick last year's (last Sunday's date in January month) date.
In detail - I want T-SQL code to produce expected result from below table
Current day T-SQL code answer expected result
2017-02-05 2017-01-29 2016-01-31
2017-01-05 2016-01-31 2015-01-25
2018-02-19 2018-01-28 2017-01-29
2018-01-19 2017-01-29 2016-01-31
2019-02-28 2019-01-27 2018-01-28
Any help please.
The best thing for this question is a numbers and date table. This answer shows you how to create one. Such a table is very handsome in many situations...
If I understand this correctly, you want the last Sunday in January of the previous year in all cases? Try this:
DECLARE #dummy TABLE(ID INT IDENTITY,YourDate DATE);
INSERT INTO #dummy VALUES
('2017-02-05'),('2017-01-05'),('2018-02-19'),('2018-01-19'),('2019-02-28');
WITH Years AS
(
SELECT * FROM (VALUES(2010),(2011),(2012),(2013),(2014),(2015),(2016),(2017),(2018),(2019),(2020)) AS t(Yr)
)
,LastSundays AS
(
SELECT Yr AS TheYear
,DATEADD(DAY,(DATEPART(WEEKDAY,LastOfJanuary) % 7)*(-1),LastOfJanuary) AS LastSundayOfJanuary
FROM Years
CROSS APPLY(SELECT CAST(CAST(Yr AS VARCHAR(4)) + '0131' AS DATE)) AS t(LastOfJanuary)
)
SELECT *
FROM #dummy AS d
INNER JOIN LastSundays AS ls ON YEAR(DATEADD(YEAR,-1,d.YourDate))=ls.TheYear;
The result (I do not understand row 2 and 4 completely...)
ID YourDate TheYear LastSundayOfJanuary
1 2017-02-05 2016 2016-01-31
2 2017-01-05 2016 2016-01-31 <--Your sample data is different...
3 2018-02-19 2017 2017-01-29
4 2018-01-19 2017 2017-01-29 <--Your sample data is different...
5 2019-02-28 2018 2018-01-28
Hint You might need to introduce ##DATEFIRST into your calculations...
Here is a way to do it without a date table (which is still a good idea BTW). Tested on all your inputs and it delivers the correct output each time. Obviously you would refactor this a bit as it's longwinded, just to show each step.
/* The input date. */
DECLARE
#input DATE = '2019-02-28';
/* The input date less one year. */
DECLARE
#date_minus_one_year DATE = DATEADD(yy,-1,#input);
/* The year part of the input date less one year. */
DECLARE
#year_date_part INT = DATEPART(yy,#date_minus_one_year);
/* 31 Jan of the previous year. */
DECLARE
#prev_year_jan_eom DATE = CAST(CAST(#year_date_part AS VARCHAR(4))+'-01-31' AS DATE);
/* What day of the week is 31 Jan of the previous year? */
DECLARE
#previous_eom_dw_part INT = DATEPART(dw,#prev_year_jan_eom);
/* Offest 31 Jan to the previous Sunday, won't change if the 31st is itself a Sunday. */
DECLARE
#output DATE = DATEADD(dd,1 - #previous_eom_dw_part,#prev_year_jan_eom);
/* Input and output */
SELECT
#input input
,#output [output];
I didn't think of a way to do it without the conditional in a case. It also uses the trick of casting a numeric year value to a January 1st date.
select case
when
datepart(dayofyear, dt) >
31 - datepart(weekday, dateadd(day, 30, cast(year(dt) as varchar(4))))
then
dateadd(day,
31 - datepart(weekday, dateadd(day, 30, cast(year(dt) as varchar(4)))),
cast(year(dt) as varchar(4))
)
else
dateadd(day,
31 - datepart(weekday, dateadd(day, 30, cast(year(dt) - 1 as varchar(4)))),
cast(year(dt) - 1 as varchar(4))
)
end
from (values
('20100201'), ('20110301'), ('20120401'),
('20130501'), ('20140601'), ('20150701'),
('20160801'), ('20170901'), ('20181001')
) t(dt)
Just for fun (untested)
select
dateadd(week,
-52 * ceil(sign(datediff(day, dt, hs)) + 0.5),
js
)
from
(select <date> dt) as t
cross apply
(
select 31 - datepart(weekday,
datefromparts(year(dt), 1, 31) as js
) t2;
SELECT
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(DATEADD(year,-1,GetDate())) = 1 THEN CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) - 1 ELSE CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)

Find first date of previous week in SQL Server

I have some dates and week numbers and first day of week is 5 (Friday) in SQL Server. Now I want to calculate previous week and week start date from this below query.
DECLARE #LocationID tinyint = 1,
#FromDate date = '2016-05-20',
#ToDate date = '2016-05-29';
--Step1: ==================================================================
--SET first day of the week of the year
DECLARE #CurrentDayOfWeek INT
SET DATEFIRST 1 -- normalize current dkoray of week to Monday
SET #CurrentDayOfWeek = DATEPART(DW, DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0))
SET DATEFIRST #CurrentDayOfWeek -- first day of week is now 5 (Friday)
--SELECT #CurrentDayOfWeek
-----Get Weekend number--------------
DECLARE #WeekStart int, #WeekEnd int
SET #WeekStart=(SELECT { fn WEEK( #FromDate) })
SET #WeekEnd=(SELECT { fn WEEK( #ToDate) })
;WITH AllDate AS
(
SELECT #FromDate as TheDate
UNION ALL
SELECT DATEADD(DAY, 1, TheDate)
FROM AllDate
WHERE DATEADD(DAY, 1, TheDate) <= #ToDate
),
AllDateDetail AS
(
SELECT TheDate,
DATEPART(WEEK, TheDate) AS WeekNumber,
YEAR(TheDate) AS [Year],
UPPER(CONVERT(NVARCHAR(3),DATENAME(WEEKDAY, TheDate))) AS [DayName]
FROM AllDate
)
SELECT
*
, CONVERT(DATE,DATEADD(WK, DATEDIFF(WK, 0, TheDate), 0)) AS LastWeekStart
, { fn WEEK( CONVERT(DATE,DATEADD(WK, DATEDIFF(WK, 0, TheDate) - 1, 0))) } AS WeekNumber
FROM AllDateDetail
--Select dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) as LastWeekStart
--Select dateadd(wk, datediff(wk, 0, getdate()), 0) as ThisWeekStart
--Select dateadd(wk, datediff(wk, 0, getdate()) + 1, 0) as NextWeekStart
The current result of this query:
Expected result:
TheDate WeekNumber [Year] [DayName] LastWeekStart LastWeekNumber
20-05-2016 21 2016 FRI 13-05-2016 20
21-05-2016 21 2016 SAT 13-05-2016 20
22-05-2016 21 2016 SUN 13-05-2016 20
23-05-2016 21 2016 MON 13-05-2016 20
24-05-2016 21 2016 TUE 13-05-2016 20
25-05-2016 21 2016 WED 13-05-2016 20
26-05-2016 21 2016 THU 13-05-2016 20
27-05-2016 22 2016 FRI 20-05-2016 21
28-05-2016 22 2016 SAT 20-05-2016 21
29-05-2016 22 2016 SUN 20-05-2016 21
Can you help me? Thanks
Here's some handy ways of calculating First/Last day of This/Last week respecting DATEFIRST that I blogged a couple of weeks ago.
SET DATEFIRST 5 --Friday
-- Start/End of Weeks respecting DATEFIRST
SELECT DATEADD(DAY, 1-DATEPART(WEEKDAY, GETDATE()), GETDATE()) 'First Day of Current Week (DATEFIRST)';
SELECT DATEADD(DAY, 7-DATEPART(WEEKDAY, GETDATE()), GETDATE()) 'Last Day of Current Week (DATEFIRST)';
SELECT DATEADD(DAY, -6-DATEPART(WEEKDAY, GETDATE()), GETDATE()) 'First Day of Last Week (DATEFIRST)';
SELECT DATEADD(DAY, 0-DATEPART(WEEKDAY, GETDATE()), GETDATE()) 'Last Day of Last Week (DATEFIRST)';
(Gratuitous blog promo https://www.rednotebluenote.com/2016/04/first-day-of-the-week-and-datefirst/ )

Query not displaying the week value as 0

SELECT datediff(week, dateadd(week, datediff(week, 0, dateadd(month, datediff(month, 0, EntryDate), 0)), 0), EntryDate - 1) + 1 as week,
count(UserID) as balance
FROM table_points
where right(convert(varchar, EntryDate, 106), 8)='Mar 2015'
GROUP BY datediff(week, dateadd(week, datediff(week, 0, dateadd(month, datediff(month, 0, EntryDate), 0)), 0), EntryDate - 1) + 1
When i execute this query i get result for 4th and 5th week values but not for others week. Like
week balance
4 80
5 100
In first 3 weeeks there is no values in database so it will not showing the values . Can any one bring 0 value for 1st , 2nd and 3rd week.
I want result as
week balance
1 0
2 0
3 0
4 80
5 100
can any one help me out.
Create a calendar/date table, including all possible dates/weeks, and from there left join the table_points table.
If no data is present in table_points, it will return 0 for those weeks.
If no dates are present in a table, it's impossible to select these and get a zero.
Example:
SELECT d.week, count(t.UserID)
FROM dates d left join table_points t on
d.date = t.EntryDate
where right(convert(varchar, d.date, 106), 8)='Mar 2015'
group by d.week
A date table can be very useful for many applications and could be filled like:
date week year month WeekOfMonth DayOfWeek Day Month
2015-03-01 18 2015 3 1 5 Friday March
2015-03-02 18 2015 3 1 6 Friday March
2015-03-03 18 2015 3 1 7 Sunday March
2015-03-04 19 2015 3 2 1 Monday March
This works like PSVSupporter's solution but uses a CTE to get a date list instead of using another table:
;WITH Dates AS (
SELECT
[Date] = CONVERT(DATETIME,'03/01/2015')
UNION ALL SELECT
[Date] = DATEADD(DAY, 1, [Date])
FROM
Dates
WHERE
Date < '03/31/2015'
)
SELECT
datediff(week, dateadd(week, datediff(week, 0, dateadd(month, datediff(month, 0, ds.Date), 0)), 0), ds.Date - 1) + 1 as week,
count(tp.UserID) as balance
FROM Dates ds
left join table_points tp on tp.EntryDate = ds.Date
WHERE right(convert(varchar, ds.Date, 106), 8)='Mar 2015'
GROUP BY datediff(week, dateadd(week, datediff(week, 0, dateadd(month, datediff(month, 0, ds.Date), 0)), 0), ds.Date - 1) + 1
I took CTE from https://stackoverflow.com/a/7824893/3309109

MSSQL - Getting last 6 weeks returns last 8 weeks

I am having a problem with week numbers. The customers week starts on a Tuesday, so ends on a Monday. So I have done:
Set DateFirst 2
When I then use
DateAdd(ww,#WeeksToShow, Date)
It occasionally gives me 8 weeks of information. I think it is because it goes over to the previous year, but I am not sure how to fix it.
If I do:
(DatePart(dy,Date) / 7) - #WeeksToShow
Then it works better, but obviously doesn't work going through to previous years as it just goes to minus figures.
Edit:
My currently SQL (If it helps at all without any data)
Set DateFirst 2
Select
DATEPART(yyyy,SessionDate) as YearNo,
DATEPART(ww,SessionDate) as WeekNo,
DATEADD(DAY, 1 - DATEPART(WEEKDAY, SessionDate + SessionTime), CAST(SessionDate +SessionTime AS DATE)) [WeekStart],
DATEADD(DAY, 7 - DATEPART(WEEKDAY, SessionDate + SessionTime), CAST(SessionDate + SessionTime AS DATE)) [WeekEnd],
DateName(dw,DATEADD(DAY, 7 - DATEPART(WEEKDAY, SessionDate + SessionTime), CAST(SessionDate + SessionTime AS DATE))) as WeekEndName,
Case when #ConsolidateSites = 1 then 0 else SiteNo end as SiteNo,
Case when #ConsolidateSites = 1 then 'All' else CfgSites.Name end as SiteName,
GroupNo,
GroupName,
DeptNo,
DeptName,
SDeptNo,
SDeptName,
PluNo,
PluDescription,
SUM(Qty) as SalesQty,
SUM(Value) as SalesValue
From
PluSalesExtended
Left Join
CfgSites on PluSalesExtended.SiteNo = CfgSites.No
Where
Exists (Select Descendant from DescendantSites where Parent in (#SiteNo) and Descendant = PluSalesExtended.SiteNo)
AND (DATEPART(WW,SessionDate + SessionTime) !=DATEPART(WW,GETDATE()))
AND SessionDate + SessionTime between DATEADD(ww,#NumberOfWeeks * -1,#StartingDate) and #StartingDate
AND TermNo = 0
AND PluEntryType <> 4
Group by
DATEPART(yyyy,SessionDate),
DATEPART(ww,SessionDate),
DATEADD(DAY, 1 - DATEPART(WEEKDAY, SessionDate + SessionTime), CAST(SessionDate +SessionTime AS DATE)),
DATEADD(DAY, 7 - DATEPART(WEEKDAY, SessionDate + SessionTime), CAST(SessionDate + SessionTime AS DATE)),
Case when #ConsolidateSites = 1 then 0 else SiteNo end,
Case when #ConsolidateSites = 1 then 'All' else CfgSites.Name end,
GroupNo,
GroupName,
DeptNo,
DeptName,
SDeptNo,
SDeptName,
PluNo,
PluDescription
order by WeekEnd
There are two issues here, the first is that I suspect you are defining 8 weeks of data as having 8 different values for DATEPART(WEEK, in which case you can replicate the root cause of the issue by looking at what ISO would define as the first week of 2015:
SET DATEFIRST 2;
SELECT Date, Week = DATEPART(WEEK, Date)
FROM (VALUES
('20141229'), ('20141230'), ('20141231'), ('20150101'),
('20150102'), ('20150103'), ('20150104')
) d (Date);
Which gives:
Date Week
-----------------
2014-12-29 52
2014-12-30 53
2014-12-31 53
2015-01-01 1
2015-01-02 1
2015-01-03 1
2015-01-04 1
So although you only have 7 days, you have 3 different week numbers. The problem is that DATEPART(WEEK is quite a simplistic function, and will simply return the number of week boundaries passed since the first day of the year, a better function would be ISO_WEEK since this takes into account year boundaries nicely:
SET DATEFIRST 2;
SELECT Date, Week = DATEPART(ISO_WEEK, Date)
FROM (VALUES
('20141229'), ('20141230'), ('20141231'), ('20150101'),
('20150102'), ('20150103'), ('20150104')
) d (Date);
Which gives:
Date Week
-----------------
2014-12-29 1
2014-12-30 1
2014-12-31 1
2015-01-01 1
2015-01-02 1
2015-01-03 1
2015-01-04 1
The problem is, that this does not take into account that the week starts on Tuesday, since the ISO week runs Monday to Sunday, you could adapt your usage slightly to get the week number of the day before:
SET DATEFIRST 2;
SELECT Date, Week = DATEPART(ISO_WEEK, DATEADD(DAY, -1, Date))
FROM (VALUES
('20141229'), ('20141230'), ('20141231'), ('20150101'),
('20150102'), ('20150103'), ('20150104')
) d (Date);
Which would give:
Date Week
-----------------
2014-12-29 52
2014-12-30 1
2014-12-31 1
2015-01-01 1
2015-01-02 1
2015-01-03 1
2015-01-04 1
So Monday the 29th December is now recognized as the previous week. The problem is that there is no ISO_YEAR built in function, so you will need to define your own. This is a fairly trivial function, even so I almost never create scalar functions because they perform terribly, instead I use an inline table valued function, so for this I would use:
CREATE FUNCTION dbo.ISOYear (#Date DATETIME)
RETURNS TABLE
AS
RETURN
( SELECT IsoYear = DATEPART(YEAR, #Date) +
CASE
-- Special cases: Jan 1-3 may belong to the previous year
WHEN (DATEPART(MONTH, #Date) = 1 AND DATEPART(ISO_WEEK, #Date) > 50) THEN -1
-- Special case: Dec 29-31 may belong to the next year
WHEN (DATEPART(MONTH, #Date) = 12 AND DATEPART(ISO_WEEK, #Date) < 45) THEN 1
ELSE 0
END
);
Which just requires a subquery to be used, but the extra typing is worth it in terms of performance:
SET DATEFIRST 2;
SELECT Date,
Week = DATEPART(ISO_WEEK, DATEADD(DAY, -1, Date)),
Year = (SELECT ISOYear FROM dbo.ISOYear(DATEADD(DAY, -1, Date)))
FROM (VALUES
('20141229'), ('20141230'), ('20141231'), ('20150101'),
('20150102'), ('20150103'), ('20150104')
) d (Date);
Or you can use CROSS APPLY:
SET DATEFIRST 2;
SELECT Date,
Week = DATEPART(ISO_WEEK, DATEADD(DAY, -1, Date)),
Year = y.ISOYear
FROM (VALUES
('20141229'), ('20141230'), ('20141231'), ('20150101'),
('20150102'), ('20150103'), ('20150104')
) d (Date)
CROSS APPLY dbo.ISOYear(d.Date) y;
Which gives:
Date Week Year
---------------------------
2014-12-29 52 2014
2014-12-30 1 2015
2014-12-31 1 2015
2015-01-01 1 2015
2015-01-02 1 2015
2015-01-03 1 2015
2015-01-04 1 2015
Even with this method, by simply getting a date 6 weeks ago you sill still end up with 7 weeks if the date you are using is not a Tuesday, because you will have 5 full weeks, and a part week at the start and a part week at the end, this is the second issue. So you need to make sure your start date is a Tuesday. The following will get you Tuesday of 7 weeks ago:
SELECT CAST(DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), DATEADD(WEEK, -6, GETDATE())) AS DATE);
The logic of this is explained better in this answer, the following is the part that will get the start of the week (based on your datefirst settings):
SELECT DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), GETDATE());
Then all I have done is substitute the second GETDATE() with DATEADD(WEEK, -6, GETDATE()) so that it is getting the start of the week 6 weeks ago, then there is just a cast to date to remove the time element from it.
This will get you current week + 5 previous weeks starting tuesday:
WHERE dateadd(week, datediff(d, 0, getdate()-1)/7 - 4, 1) <= yourdatecolumn
This will show examples:
DECLARE #wks int = 6 -- Weeks To Show
SELECT
dateadd(week, datediff(d, 0, getdate()-1)/7 - 4, 1) tuesday5weeksago,
dateadd(week, datediff(d, 0, getdate()-1)/7 - 5, 1) tuesday6weeksago,
dateadd(week, datediff(d, 0, getdate()-1)/7 - 6, 1) tuesday7weeksago,
dateadd(week, datediff(d, 0, getdate()-1)/7 - #wks + 1, 1) tuesdaydynamicweeksago
Result:
tuesday5weeksago tuesday6weeksago tuesday7weeksago tuesdaydynamicweeksago
2015-01-27 2015-01-20 2015-01-13 2015-01-20