如何让Northwind的ROLLUP查询中各客户各年份的月份按时间顺序排序?
解决Northwind数据库ROLLUP分组后月份按时间排序的问题
你的查询里月份按DATENAME(MM, o.orderdate)的字符串字典序排列(比如April排在January之前),而非实际时间顺序。要修正这个问题,需要保留月份的数字序号用于排序,同时不破坏ROLLUP的汇总逻辑。
修正后的查询代码
SELECT c.CompanyName, DATEPART(YYYY, o.orderdate) AS 'Yr', DATENAME(MM, o.orderdate) AS 'Mth', COUNT(o.OrderID) AS 'Orders' FROM Orders o INNER JOIN Customers c ON o.customerid = c.CustomerID GROUP BY ROLLUP ( c.CompanyName, DATEPART(YYYY, o.orderdate), DATEPART(MM, o.orderdate), -- 加入月份数字用于排序依据 DATENAME(MM, o.orderdate) ) ORDER BY c.CompanyName, DATEPART(YYYY, o.orderdate), DATEPART(MM, o.orderdate) -- 按月份数字排序,保证时间顺序
代码说明
- 在
GROUP BY ROLLUP中添加DATEPART(MM, o.orderdate),由于月份数字和名称一一对应,不会改变分组结果,但能提供时间排序的依据。 ORDER BY子句使用月份数字排序,确保同一年份下的月份按1-12的时间顺序排列。- ROLLUP生成的汇总行(
Mth为NULL的行)会自然排在对应年份的所有月份之后,符合汇总逻辑。
更清晰的CTE写法
如果觉得GROUP BY字段过多,可先用CTE提取日期分组字段,让逻辑更直观:
WITH OrderDateGroups AS ( SELECT c.CompanyName, DATEPART(YYYY, o.orderdate) AS Yr, DATEPART(MM, o.orderdate) AS MonthNum, DATENAME(MM, o.orderdate) AS Mth, o.OrderID FROM Orders o INNER JOIN Customers c ON o.customerid = c.CustomerID ) SELECT CompanyName, Yr, Mth, COUNT(OrderID) AS Orders FROM OrderDateGroups GROUP BY ROLLUP (CompanyName, Yr, MonthNum, Mth) ORDER BY CompanyName, Yr, MonthNum
内容的提问来源于stack exchange,提问作者Quavo1504
相关产品推荐
相关产品推荐

