我正在尝试针对该月的总订单生成每月接受订单的报告。例如,我有一个表Orders
,如下所示:
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
并希望得到如此结果:
[Month] Accepted Total
------- -------- -----
2013-05 1 2
2013-06 2 3
2013-08 2 2
2013-10 1 1
2014-01 2 2
我该如何解决?
答案 0 :(得分:2)
假设你永远不会有时间组件,这应该可以正常工作:
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];
(如果您使用的是SQL Server 2008或更高版本,则应使用DATE
数据类型以防止必须处理任何错误的小时/分钟。)
如果你有时可能有几小时/几分钟,而你没有在2008年或更高时间,那么:
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];
我强烈建议您避免使用字符串转换进行分组的任何解决方案。日期/时间数学在SQL Server中比转换为字符串更有效。此外,如果您希望客户端提供2013-05
之类的内容,请使用Format(),ToString()等在客户端上应用该字符串格式。
答案 1 :(得分:1)
要获得yyyy-dd格式,您可以使用此
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)
答案 2 :(得分:0)
试一试:
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)