patternsqlMinor
Count and group rows for six months prior
Viewed 0 times
sixrowsgroupformonthspriorandcount
Problem
I've written the following query for SQL server:
This code counts up how many meetings there were for the six months prior to this one. It works perfectly, but I'm sure there's a better way of figuring the months than I have.
SELECT YEAR(Meeting_Date) year, MONTH(Meeting_Date) month, COUNT(project) meetings
FROM
meetings
WHERE Meeting_Date BETWEEN
CAST(DATEPART(year,DATEADD(m,-6,GETDATE())) as varchar(4)) + '-' + CAST(DATEPART(month,DATEADD(m,-6,GETDATE())) as varchar(2)) + '-01'
AND
DATEADD(d,-1,CAST(DATEPART(year,GETDATE()) as varchar(4)) + '-' + CAST(DATEPART(month, GETDATE()) as varchar(2)) + '-01')
GROUP BY YEAR(Meeting_Date), MONTH(Meeting_Date)
ORDER BY YEAR(Meeting_Date), MONTH(Meeting_Date)This code counts up how many meetings there were for the six months prior to this one. It works perfectly, but I'm sure there's a better way of figuring the months than I have.
Solution
This is one of those things.... date manipulation in SQL.
For performance reasons, it is a pain to cast to
What I have found works best for me, is the following function:
The above subtracts the number of days needed to bring a date back to the first-of-the-month.
For example today, (the 28th April), would subtract
You can do your current month-manipulation to move months around once you are back on to the first-of-the-month, and then you don't have to worry about the month overflow problems..
For readability reasons, I would recommend you use variables, if you can:
For performance reasons, it is a pain to cast to
NVarchar, etc. For readability reasons, everything is a pain.....What I have found works best for me, is the following function:
DateAdd(d, 1 - DatePart(d, actualdate), actualdate)The above subtracts the number of days needed to bring a date back to the first-of-the-month.
For example today, (the 28th April), would subtract
1 - 28 (or 27) days from the 28th, to get the 1st.You can do your current month-manipulation to move months around once you are back on to the first-of-the-month, and then you don't have to worry about the month overflow problems..
For readability reasons, I would recommend you use variables, if you can:
declare @thismonth as Date = Convert(DateAdd(d, 1 - DatePart(d, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP) as Date);
declare @firstmonth as Date = DateAdd(m, -6, @thismonth);
SELECT YEAR(Meeting_Date) year,
MONTH(Meeting_Date) month,
COUNT(project) meetings
FROM
meetings
WHERE Meeting_Date BETWEEN @firstmonth AND @thismonth
GROUP BY YEAR(Meeting_Date), MONTH(Meeting_Date)
ORDER BY YEAR(Meeting_Date), MONTH(Meeting_Date)Code Snippets
DateAdd(d, 1 - DatePart(d, actualdate), actualdate)declare @thismonth as Date = Convert(DateAdd(d, 1 - DatePart(d, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP) as Date);
declare @firstmonth as Date = DateAdd(m, -6, @thismonth);
SELECT YEAR(Meeting_Date) year,
MONTH(Meeting_Date) month,
COUNT(project) meetings
FROM
meetings
WHERE Meeting_Date BETWEEN @firstmonth AND @thismonth
GROUP BY YEAR(Meeting_Date), MONTH(Meeting_Date)
ORDER BY YEAR(Meeting_Date), MONTH(Meeting_Date)Context
StackExchange Code Review Q#48407, answer score: 4
Revisions (0)
No revisions yet.