15

I think I have a tough one here... :(

I am trying to get an order count by month, even when zero. Here's the problem query:

SELECT datename(month, OrderDate) as Month, COUNT(OrderNumber) AS Orders
FROM OrderTable
WHERE OrderDate >= '2012-01-01' and OrderDate <= '2012-06-30'
GROUP BY year(OrderDate), month(OrderDate), datename(month, OrderDate)

What I'm looking to get is something like this:

Month            Orders
-----            ------
January          10
February         7
March            0
April            12
May              0
June             5

...but my query skips a row for March and May. I've tried COALESCE(COUNT(OrderNumber), 0) and ISNULL(COUNT(OrderNumber), 0) but I'm pretty sure the grouping is causing that not to work.

4

3 に答える 3

27

このソリューションでは、必要な月のリストをハードコードする必要はありません。開始日と終了日を指定するだけで、月の境界が計算されます。出力に年が含まれているため、12 か月以上をサポートし、開始日と終了日が年の境界を越えても、正しい順序で正しい月年を表示できます。

DECLARE @StartDate SMALLDATETIME, @EndDate SMALLDATETIME;

SELECT @StartDate = '20120101', @EndDate = '20120630';

;WITH d(d) AS 
(
  SELECT DATEADD(MONTH, n, DATEADD(MONTH, DATEDIFF(MONTH, 0, @StartDate), 0))
  FROM ( SELECT TOP (DATEDIFF(MONTH, @StartDate, @EndDate) + 1) 
    n = ROW_NUMBER() OVER (ORDER BY [object_id]) - 1
    FROM sys.all_objects ORDER BY [object_id] ) AS n
)
SELECT 
  [Month]    = DATENAME(MONTH, d.d), 
  [Year]     = YEAR(d.d), 
  OrderCount = COUNT(o.OrderNumber) 
FROM d LEFT OUTER JOIN dbo.OrderTable AS o
  ON o.OrderDate >= d.d
  AND o.OrderDate < DATEADD(MONTH, 1, d.d)
GROUP BY d.d
ORDER BY d.d;
于 2012-07-14T01:33:03.563 に答える
4

クエリでは必要な月を推測できないため、必要な月をどこかに保存し、テーブルに結合してからグループ化する必要があります。何かのようなもの:

;With Months (Month) 
AS
(

    select 'January' as Month
    UNION
    select 'February' as Month
    UNION
    select 'March' as Month
    UNION
    select 'April' as Month
    UNION
    select 'May' as Month
    UNION
    select 'June' as Month
    UNION
    select 'July' as Month
    UNION
    select 'August' as Month
    UNION
    select 'September' as Month
    UNION
    select 'October' as Month
    UNION
    select 'November' as Month
    UNION
    select 'December' as Month

)
--Also you could have them in a "Months" Table

次にJOIN、このテーブルとテーブルを合わせます。

   Select 
    SELECT datename(month, OrderDate) as Month, COUNT(OrderNumber) 
    FROM Months T1
    LEFT JOIN OrderTable T2 on datename(month, T2.OrderDate) = T2.Month
    WHERE (T2.OrderDate >= '2012-01-01' and T2.OrderDate <= '2012-06-30') 
OR T2.OrderDate IS NULL --So will show you the months with no rows
    GROUP BY year(T2.OrderDate), month(T2.OrderDate), datename(month, T2.OrderDate)

それがうまくいくことを願っています!

于 2012-07-14T01:13:53.820 に答える