Reputation: 57
I am trying to generate a report for accepted orders each month against the total orders for that month. For example, I have a table Orders
like so:
Order_Id Submit_Date Order_Status
-------- ----------- ------------
1 20130501 Accepted
2 20130509 Rejected
3 20130610 Accepted
4 20130614 Accepted
5 20130626 Rejected
6 20130802 Accepted
7 20130801 Accepted
8 20131014 Accepted
9 20140116 Rejected
10 20140121 Rejected
And would like to get the results like so:
[Month] Accepted Total
------- -------- -----
2013-05 1 2
2013-06 2 3
2013-08 2 2
2013-10 1 1
2014-01 2 2
How do I go about it?
Upvotes: 0
Views: 65
Reputation: 77
Try it:
SELECT
CONVERT(VARCHAR(4), YEAR(Date)) + '-' + CONVERT(VARCHAR(2), MONTH(Date)) Period,
SUM(CASE WHEN Status = 'Accepted' THEN 1 ELSE 0) Accepted,
COUNT(*) Total
FROM Orders
GROUP BY YEAR(Date), MONTH(Date)
ORDER BY YEAR(Date), MONTH(Date)
Upvotes: 0
Reputation:
To get yyyy-dd format you can use this
SELECT CONVERT(VARCHAR(7),[Date],20)
,COUNT(CASE WHEN [status] = 'Accepted' THEN 1
ELSE NULL END) AS 'Accepted'
,COUNT(*) AS Total
FROM Orders
GROUP BY CONVERT(VARCHAR(7),[Date],20)
Upvotes: 1
Reputation: 280429
Assuming you will never have a time component, this should work just fine:
DECLARE @d TABLE([Order] INT, [Date] DATETIME, [Status] CHAR(8));
INSERT @d VALUES
(1 ,'20130501','Accepted'),
(2 ,'20130509','Rejected'),
(3 ,'20130610','Accepted'),
(4 ,'20130614','Accepted'),
(5 ,'20130626','Rejected'),
(6 ,'20130802','Accepted'),
(7 ,'20130801','Accepted'),
(8 ,'20131014','Accepted'),
(9 ,'20140116','Rejected'),
(10,'20140121','Rejected');
SELECT
[Month] = DATEADD(DAY, 1-DAY([Date]), [Date]),
Accepted = SUM(CASE WHEN [Status] = 'Accepted' THEN 1 ELSE 0 END),
COUNT(*)
FROM @d
GROUP BY DATEADD(DAY, 1-DAY([Date]), [Date])
ORDER BY [Month];
(And if you are on SQL Server 2008 or newer, you should use the DATE
data type to prevent having to deal with any errant hours/minutes.)
If you can have hours/minutes sometimes, and you're not on 2008 or greater, then:
SELECT
[Month] = DATEADD(MONTH, DATEDIFF(MONTH, 0, [Date]), 0),
Accepted = SUM(CASE WHEN [Status] = 'Accepted' THEN 1 ELSE 0 END),
COUNT(*)
FROM @d
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, [Date]), 0)
ORDER BY [Month];
I strongly recommend avoiding any solutions that group by using string conversions. Date/time math is much more efficient in SQL Server than converting to strings. Also if you want the client side to present things like 2013-05
, use Format(), ToString() etc. to apply that string formatting on the client.
Upvotes: 2