Find the count for last year same week in sql - sql

I am using the below query to find the count from a table based on a date for the last 5-6 weeks as below
BEGIN
SET datefirst 1;
DECLARE #BeginDate datetime= '2016-10-10'
SELECT
count(*) as Total
, datepart(wk, DateCreated) as WeekNumber
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104) as WeekStartDate
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104) as WeekEndDate
FROM TABLESES
WHERE
CONVERT(date,DateCreated) >= DATEADD(DAY, -42, #BeginDate)
AND CONVERT(date,DateCreated) <= DATEADD(DAY, 6, #BeginDate)
GROUP BY datepart(wk, DateCreated)
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104)
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104)
ORDER BY datepart(wk, DateCreated)
END
This will return a result set like below:
Total WeekNumber WeekStartDate WeekEndDate
51295 36 29.08.2016 04.09.2016
48133 37 05.09.2016 11.09.2016
38991 38 12.09.2016 18.09.2016
38074 39 19.09.2016 25.09.2016
37192 40 26.09.2016 02.10.2016
20835 41 03.10.2016 09.10.2016
23781 42 10.10.2016 16.10.2016
Now I want to add one more column in the end with count for the same week number in last year.
Can I achieve the same in this query itself? Or should I write a totally different query for it? And how can I make this query?

You can use UNION with DATEDIFF to get the same thing for the previous year:
SELECT
count(*) as Total
, datepart(wk, DateCreated) as WeekNumber
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104) as WeekStartDate
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104) as WeekEndDate
FROM TABLESES
WHERE
CONVERT(date,DateCreated) >= DATEADD(DAY, -42, #BeginDate)
AND CONVERT(date,DateCreated) <= DATEADD(DAY, 6, #BeginDate)
GROUP BY datepart(wk, DateCreated)
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104)
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104)
UNION ALL
SELECT
count(*) as Total
, datepart(wk, DATEDIFF(year,1,DateCreated )) as WeekNumber
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DATEDIFF(year,1,DateCreated ))/7,0),104) as WeekStartDate
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DATEDIFF(year,1,DateCreated ))/7,6),104) as WeekEndDate
FROM TABLESES
WHERE
CONVERT(date,DateCreated) >= DATEADD(DAY, -42, #BeginDate)
AND CONVERT(date,DateCreated) <= DATEADD(DAY, 6, #BeginDate)
GROUP BY datepart(wk, DATEDIFF(year,1,DateCreated ))
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DATEDIFF(year,1,DateCreated ))/7,0),104)
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DATEDIFF(year,1,DateCreated ))/7,6),104)
ORDER BY datepart(wk, DATEDIFF(year,1,DateCreated ))

Put your end-result to a temp table and then do something like this:
Be sure to check your date logic with previous year. But hope you get the logic. I havent tested if your "Version" is correct as i have wroted, but i hope you get the picture.
Result with test version
TEST Version:
DECLARE #Weeks1 TABLE(
Total int,
Weeknumber INT,
WeekStartDate nvarchar(50),
WeekEndDate nvarchar(50)
)
DECLARE #Weeks2 TABLE(
Total int,
Weeknumber INT,
WeekStartDate nvarchar(50),
WeekEndDate nvarchar(50)
)
insert into #Weeks1 (Total,Weeknumber,WeekStartDate,Weekenddate)
values ('51295', '36' ,'29.08.2016' ,'04.09.2016'),
('48133', '37' ,'05.09.2016' ,'11.09.2016'),
('38991', '38' ,'12.09.2016' ,'18.09.2016'),
('38074', '39' ,'19.09.2016' ,'25.09.2016'),
('37192', '40' ,'26.09.2016' ,'02.10.2016'),
('20835', '41' ,'03.10.2016' ,'09.10.2016'),
('23781', '42' ,'10.10.2016' ,'16.10.2016')
insert into #Weeks2 (Total,Weeknumber,WeekStartDate,Weekenddate)
values ('324234', '36' ,'29.08.2015' ,'04.09.2015'),
('22333', '37' ,'05.09.2015' ,'11.09.2015'),
('23444', '38' ,'12.09.2015' ,'18.09.2015'),
('566666', '39' ,'19.09.2015' ,'25.09.2015'),
('4345', '40' ,'26.09.2015' ,'02.10.2015'),
('8657', '41' ,'03.10.2015' ,'09.10.2015'),
('8567567', '42' ,'10.10.2015' ,'16.10.2015')
Select a.Total,b.Total as
LastYearTotal,a.Weeknumber,A.WeekStartDate,a.Weekenddate from #Weeks1 a
inner join #Weeks2 b on a.Weeknumber = b.Weeknumber
With your version:
DECLARE #Weeks1 TABLE(
Total int,
Weeknumber INT,
WeekStartDate nvarchar(50),
WeekEndDate nvarchar(50)
)
DECLARE #Weeks2 TABLE(
Total int,
Weeknumber INT,
WeekStartDate nvarchar(50),
WeekEndDate nvarchar(50)
)
BEGIN
SET datefirst 1;
DECLARE #BeginDate datetime= '2016-10-10'
insert into #Weeks1 (Total,Weeknumber,WeekStartDate,Weekenddate)
SELECT
count(*) as Total
, datepart(wk, DateCreated) as WeekNumber
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104) as WeekStartDate
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104) as WeekEndDate
FROM TABLESES
WHERE
CONVERT(date,DateCreated) >= DATEADD(DAY, -42, #BeginDate)
AND CONVERT(date,DateCreated) <= DATEADD(DAY, 6, #BeginDate)
GROUP BY datepart(wk, DateCreated)
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104)
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104)
ORDER BY datepart(wk, DateCreated)
END
BEGIN
SET datefirst 1;
DECLARE #BeginDate2 datetime= '2015-10-10'
insert into #Weeks2 (Total,Weeknumber,WeekStartDate,Weekenddate)
SELECT
count(*) as Total
, datepart(wk, DateCreated) as WeekNumber
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104) as WeekStartDate
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104) as WeekEndDate
FROM TABLESES
WHERE
CONVERT(date,DateCreated) >= DATEADD(DAY, -42, #BeginDate2)
AND CONVERT(date,DateCreated) <= DATEADD(DAY, 6, #BeginDate2)
GROUP BY datepart(wk, DateCreated)
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104)
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104)
ORDER BY datepart(wk, DateCreated)
END
Select a.Total,b.Total as
LastYearTotal,a.Weeknumber,A.WeekStartDate,a.Weekenddate from #Weeks1 a
inner join #Weeks2 b on a.Weeknumber = b.Weeknumber

If only weeks matter you can make some date calculations first and have a simpler query
SET datefirst 1;
DECLARE #BeginDate datetime = '2016-10-10'; -- must be start of the week , <= last week -6
declare #nweeks int = 6;
-- this year interval
declare #b1Date datetime = dateadd(week, -#nweeks , #BeginDate); --inclusive
declare #e1Date datetime = dateadd(week, 1 , #BeginDate); -- exclusive
declare #thisYear int = datepart(year, #b1Date);
-- previous year interval
declare #bwk int = datepart(week, #b1Date);
declare #year2 datetime= dateadd(year,datediff(year,0,#b1Date)-1,0);
declare #b2Date datetime = dateadd(week, #bwk-1, #year2);
declare #e2Date datetime = dateadd(week, #bwk + #nweeks, #year2);
-- check it
select #BeginDate, #b1Date, #e1Date, #bwk, #b2Date, #e2Date, datepart(week, #b2Date);
SELECT
count(case datepart(year, DateCreated) when #thisYear then 1 end) as TotalThisYear
, datepart(wk, DateCreated) as WeekNumber
, convert(VARCHAR(20),dateadd(week,datepart(week,DateCreated)-#bwk -1,#b1Date),104) as WeekStartDate
, convert(VARCHAR(20),dateadd(day,7*(datepart(week,DateCreated)-#bwk-1)+6,#b1Date),104) as WeekEndDate
, count(case datepart(year, DateCreated) when #thisYear-1 then 1 end) as TotalPrev
FROM TABLESES
WHERE
CONVERT(date,DateCreated) >= #b1Date AND CONVERT(date,DateCreated) <#e1Date
OR
CONVERT(date,DateCreated) >= #b2Date AND CONVERT(date,DateCreated) <#e2Date
GROUP BY datepart(wk, DateCreated)
ORDER BY datepart(wk, DateCreated)

Yes, you can use your same query but with few modifications. I have used 2 CTE's , one for your query and another for prior year weeks. Then join both on the weeknumber to fetch the needed last column as you can see below.
BEGIN
SET datefirst 1;
DECLARE #BeginDate datetime= '2016-10-10'
;WITH CTE1 as
SELECT
count(*) as Total
, datepart(wk, DateCreated) as WeekNumber
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104) as WeekStartDate
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104) as WeekEndDate
FROM TABLESES
WHERE
CONVERT(date,DateCreated) >= DATEADD(DAY, -42, #BeginDate)
AND CONVERT(date,DateCreated) <= DATEADD(DAY, 6, #BeginDate)
GROUP BY datepart(wk, DateCreated)
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104)
, convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104)
,CTE2 as
SELECT count(*) as Total
,datepart(wk, dateadd(year, -1, DateCreated)) as WeekNumber
FROM TABLESES
GROUP BY datepart(wk, dateadd(year, -1, DateCreated))
SELECT CTE1.*, CTE2.Total
FROM CTE1 JOIN CTE2
ON CTE1.WeekNumber = CTE2.WeekNumber
END

Related

SQL Server Grouping by week year error

I have the following query where i'm trying to group an average score by weeks. The issue i'm having is that all the dates are being returned as 2018. How can I get the year of the returned date to be correct
DECLARE #s DATETIME= '2017-12-18', #e DATETIME= '2018-01-15';
SELECT ROUND(AVG(CAST(MYTABLE.score AS FLOAT)), 1) AS avgScore,
DATEADD(week, DATEPART(wk, dateCreated) - 1, DATEADD(wk, DATEDIFF(wk, -1, DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0)), 0)) AS dateCreated
FROM MYTABLE
WHERE MYTABLE.dateCreated BETWEEN #s AND #e
GROUP BY DATEPART(wk, dateCreated)
ORDER BY dateCreated;
Smaple results
avgScore | dateCreated
----------------------
5.2 | 2018-12-17
4.6 | 2018-12-24
5.5 | 2018-01-01
6.5 | 2018-01-08
4.2 | 2018-01-15
Try adding
YEAR(dateCreated)
in the Group By
declare #s datetime = '2017-12-18', #e datetime = '2018-01-15';
SELECT ROUND(AVG(CAST(MYTABLE.score AS FLOAT)), 1) AS avgScore, dateadd(week,DATEPART(wk, dateCreated)-1, DATEADD(wk, DATEDIFF(wk,-1,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)), 0)) AS dateCreated
FROM MYTABLE
WHERE MYTABLE.dateCreated between #s and #e
GROUP BY YEAR(dateCreated), DATEPART(wk, dateCreated)
ORDER BY dateCreated
Being that you are grouping by week, the week is just a number. so you are discarding year.
For getting the first day of the week DATEADD(DAY, -1 + DATEPART(WEEKDAY, [DATE]), [DATE]) more appropriate and also you can use it with group by.
SET DATEFIRST 1;
declare #s datetime = '2017-12-18', #e datetime = '2018-01-15';
SELECT ROUND(AVG(CAST(MYTABLE.score AS FLOAT)), 1) AS avgScore,
DATEADD(DAY, -1 + DATEPART(WEEKDAY, dateCreated), dateCreated) AS dateCreated
FROM MYTABLE
WHERE MYTABLE.dateCreated between #s and #e
GROUP BY DATEADD(DAY, -1 + DATEPART(WEEKDAY, dateCreated), dateCreated)
ORDER BY dateCreated

Find the Same day of Previous Year Given by Current Year Date in SQL Server

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

Calendar showing null when date begins in previous year

This is the syntax I am using to create my calendar. The issue that I have is that since the startdate of Week1 is in 2012, startdate is showing as null. Is there a way to have the startdate (or enddate in other instances) populate even when it is in a different year? #Winds Of Change ---
That adds in a start date and end date where previously it was null. But what I am after is for example, I need my date range to run Sat - Wed. So let's take week 53 for 2013. The date range should be 12/28/2013 -- 01/01/14. Is there a way to tinker the calander into displaying in that format?
CREATE TABLE dbo.Calendar (
CalendarYear INT NOT NULL,
CalendarWeek INT NOT NULL,
WeekStartDate VARCHAR(50),
WeekEndDate VARCHAR(50),
CONSTRAINT PK_Calendar PRIMARY KEY (
CalendarYear,
CalendarWeek
)
)
SET DATEFIRST 6
DECLARE #StartDate DATETIME,
#NumOfDays INT
SET #StartDate = '20130101'
SET #NumOfDays = 1000;
WITH calendar
AS (
SELECT TOP (#NumOfDays) dateadd(day, row_number() OVER (
ORDER BY sc1.column_id
) - 1, #StartDate) AS CalendarDate
FROM sys.columns sc1
CROSS JOIN sys.columns sc2
)
INSERT INTO dbo.Calendar (
CalendarYear,
CalendarWeek,
WeekStartDate,
WeekEndDate
)
SELECT DATEPART(year, c.CalendarDate) AS Year,
convert(VARCHAR(100), DATEPART(week, c.CalendarDate)) AS Week, --DATEPART(week, c.CalendarDate) AS Week,
MAX(CASE DATEPART(WEEKDAY, c.CalendarDate)
WHEN 1
THEN convert(VARCHAR(50), c.CalendarDate, 101)
ELSE NULL
END) AS StartDate,
MAX(CASE DATEPART(WEEKDAY, c.CalendarDate)
WHEN 7
THEN convert(VARCHAR(50), c.CalendarDate, 101)
ELSE NULL
END) AS EndDate
FROM calendar c
GROUP BY DATEPART(year, c.CalendarDate),
DATEPART(Week, c.CalendarDate)
ORDER BY Year,
startdate,
convert(VARCHAR(100), DATEPART(week, c.CalendarDate)) --Week
SELECT *
FROM dbo.Calendar
So your problem is is that you're grouping by week and year, but at the beginning/end of the year, the year begins/ends on a different week. So if the first week starts on Wednesday, it's only a 3 day week for that Year.
I've had a small tinker, and I've got it working so that it displays the first/last day of the year as the start/end date of the week, by changing things around. Here is my modified version:
SELECT
DATEPART(year, c.CalendarDate) AS Year,
convert(VARCHAR(100), DATEPART(week, c.CalendarDate)) AS Week, --DATEPART(week, c.CalendarDate) AS Week,
convert(VARCHAR(50), MIN(c.CalendarDate), 101) AS StartDate,
convert(VARCHAR(50), MAX(c.CalendarDate), 101) AS EndDate
FROM
calendar c
GROUP BY
DATEPART(year, c.CalendarDate),
DATEPART(Week, c.CalendarDate)
ORDER BY
Year,
startdate,
convert(VARCHAR(100), DATEPART(week, c.CalendarDate)) --Week
Hope this helps.
EDIT: In response to your comment/edit, have a look at these update statements. Put them after your insert.
EDIT2: Don't use the above insert as well as the updates.
update dbo.Calendar set WeekStartDate = convert(VARCHAR(50), dateadd(day, 1, dateadd(week, -1, cast(WeekEndDate as datetime))), 101)
where WeekStartdate is null
update dbo.Calendar set WeekEndDate = convert(VARCHAR(50), dateadd(day, -1, dateadd(week, 1, WeekStartDate)), 101)
where WeekEndDate is null

write a query that will run all the days and the name of the day between two set dates [duplicate]

This question already has answers here:
Get a list of dates between two dates
(23 answers)
Closed 8 years ago.
I am trying to write a query that will run all the days and the name of the day between two set dates.
Example:
Date1 = 12/28/2005
Date2 = 12/30/2006
Results:
12/28/2005 Wednesday
12/29/2005 Thursday
12/30/2005 Friday
12/31/2005 Saturday
01/01/2006 Sunday
01/02/2006 Monday
01/03/2006 Tuesday
Any help is appreciated!
You may check this fiddle.
The code:
DECLARE #Date1 DATETIME
DECLARE #Date2 DATETIME
SET #Date1 = '20051228'
SET #Date2 = '20061230'
;WITH cteSequence ( SeqNo) as
(
SELECT 0
UNION ALL
SELECT SeqNo + 1
FROM cteSequence
WHERE SeqNo < DATEDIFF(d,#Date1,#Date2)
)
SELECT CONVERT(VARCHAR,DATEADD(d,SeqNo,#Date1),1) + ' ' + DATENAME(dw,DATEADD(d,SeqNo,#Date1))
FROM cteSequence
OPTION ( MAXRECURSION 0);
GO
You can use that table-valued function:
create function DateTable
(
#FirstDate datetime,
#LastDate datetime,
#handle nvarchar(10)='day',
#handleQuantity int=1
)
returns #datetable table (
[date] datetime
)
AS
begin
with CTE_DatesTable
as
(
select #FirstDate AS [date]
union ALL
select case #handle
when 'month' then dateadd(month, #handleQuantity, [date])
when 'year' then dateadd(year, #handleQuantity, [date])
when 'hour' then dateadd(hour, #handleQuantity, [date])
when 'minute' then dateadd(minute, #handleQuantity, [date])
when 'second' then dateadd(second, #handleQuantity, [date])
else dateadd(day, #handleQuantity, [date])
end
from CTE_DatesTable
where #LastDate >=
case #handle
when 'month' then dateadd(month, #handleQuantity, [date])
when 'year' then dateadd(year, #handleQuantity, [date])
when 'hour' then dateadd(hour, #handleQuantity, [date])
when 'minute' then dateadd(minute, #handleQuantity, [date])
when 'second' then dateadd(second, #handleQuantity, [date])
else DATEADD(day, #handleQuantity, [date])
end
)
insert #datetable ([date])
select [date] from CTE_DatesTable
option (MAXRECURSION 0)
return
end
You can call it like:
select [date],datepart(weekday,[date]) from dbo.DateTable('12/28/2005','12/30/2006',default,default)
You didn't specify your DBMS so I'm assuming Postgres:
select i::date, to_char(i, 'Day')
from generate_series(timestamp '2005-12-28 00:00:00',
timestamp '2006-12-30 00:00:00', interval '1' day) i;
The ANSI SQL solution for this would be:
with recursive date_list (the_date) as (
values ( date '2005-12-28' )
union all
select cast(p.the_date + interval '1' day as date)
from date_list p
where p.the_date <= date '2006-12-30
)
select *
from date_list;

Returns date range by quarter?

I am looking for a query that can returns a series of date range that is one quarter long.
For example, if the input is 2/1/2013 and 3/31/2014, then the output would look like:
start end
2/1/2013 4/30/2013
5/1/2013 7/31/2013
8/1/2013 10/31/2013
11/1/2013 1/31/2014
2/1/2014 3/31/2014
Notice that the last quarter is only 2 months long. Thanks for help in advance.
Just want to add that this is what I did after I did a bit of googling. I was thinking of some more efficient way but I think this is sufficient for my purpose. The first part is to populate a date table, the second part to calculate the quarter range.
DECLARE #StartDate SMALLDATETIME
DECLARE #EndDate SMALLDATETIME
SET #StartDate = '1/1/2011'
SET #EndDate = '12/31/2011'
-- creates a date table, not needed if there is one already
DECLARE #date TABLE ( [date] SMALLDATETIME )
DECLARE #offset INT
SET #offset = 0
WHILE ( #offset < DATEDIFF(dd, #StartDate, DATEADD(dd, 1, #EndDate)) )
BEGIN
INSERT INTO #date ( [date] )
VALUES ( DATEADD(dd, #offset, #StartDate) )
SELECT #offset = #offset + 1
END ;
WITH dateCTE
AS ( SELECT ROW_NUMBER() OVER ( ORDER BY [date] ASC ) AS qID ,
[date] AS qStart ,
CASE WHEN DATEADD(dd, -1, DATEADD(q, 1, [date])) > #EndDate
THEN #EndDate
ELSE DATEADD(dd, -1, DATEADD(q, 1, [date]))
END AS qEnd
FROM #date
WHERE [date] = #StartDate
OR ( DATEDIFF(mm, #StartDate, [date]) % 3 = 0
AND DATEPART(dd, [date]) = DATEPART(dd,
#StartDate)
)
)