如何对已过滤的行进行分组,而不是按月过滤

时间:2014-01-22 20:13:57

标签: sql sql-server sql-server-2008-r2

我正在尝试针对该月的总订单生成每月接受订单的报告。例如,我有一个表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

我该如何解决?

3 个答案:

答案 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)