2012-03-15 10 views
2

1か月間に製品の合計売上を計算しようとしていますが、売上がない空の月を含めたいと思います。最新の12ヶ月。SQL Server:空の月を含む月間総売上高を計算

これまでのコードです。

declare 
@ProductNo int 

set @ProductNo = 1234 

SELECT 
YEAR(o.OrderDate) as 'Year', MONTH(o.OrderDate) as 'Month', sum(Amount) as 'Units sold',[ProductNo] 

    FROM [OrderLine] ol 
    inner join [Order] o on ol.OrderNo = o.OrderNo 
    where ProductNo = @ProductNo 

    Group by ProductNo, YEAR(o.OrderDate), Month(o.OrderDate) 
    Order by ProductNo, YEAR(o.OrderDate), Month(o.OrderDate) 

これは

Year Month Units sold 
2011 6  2 
2011 10  1 
2011 11  1 
2012 2  1 

を返します。しかし、私はそれを返すようにしたいと思います。

Year Month Units sold 
2011 4  0 
2011 5  0 
2011 6  2 
2011 7  0 
2011 8  0  
2011 9  0 
2011 10  1 
2011 11  1 
2011 12  0 
2012 1  0 
2012 2  2 
2012 3  0 

私は私はあなたがカレンダーのテーブルを持っていることを知っている前に、私がやったSQL Server 2008のR2 SP1

+0

が重複する可能性:http://stackoverflow.com/questions/9691824/handling-non-existent-values-in-sql-query-expression-for-ssrs- chart/9692399#9692399 –

+1

本当に月を保持するために余分なテーブルを作成するのは嫌いです。 – gulbaek

+0

あなたができることは、与えられた開始日と終了日の月のテーブルを返すテーブル値関数を作成することです。 MIN(OrderDate)とMAX(OrderDate)をそれぞれ使用できます。私たちは、私たちの環境で同様のものを使用します。 – tobias86

答えて

2

を使用しています。私はmaster.dbo.spt_valuesを使用して過去12ヶ月連続(現行を含む)を生成しています。

declare @ProductNo int 

    set @ProductNo = 1234 

select MONTH(d.date), YEAR(d.date), isnull(t.amnt, 0) as [Units sold] from (
    SELECT 
     YEAR(o.OrderDate) as 'Year', 
     MONTH(o.OrderDate) as 'Month', 
     sum(Amount) as amnt, 
     [ProductNo] 
    FROM [OrderLine] ol 
    inner join [Order] o on ol.OrderNo = o.OrderNo 
    where ProductNo = @ProductNo 
    group by ProductNo, YEAR(o.OrderDate), Month(o.OrderDate) 
) t 
right join (
    select dateadd(mm, -number, getdate()) as date 
    from master.dbo.spt_values 
    where type = 'p' and number < 12 
) d on year(d.date) = t.[year] and month(d.date) = t.[month] 
order by YEAR(d.date), MONTH(d.date) 
+0

このエラーが発生しています。列 "d"またはユーザー定義関数、または "d.year"を集計できないか、名前があいまいです。どこで定義しましたか? – gulbaek

+0

あなたの答えをお寄せいただきありがとうございます。回答を提出して編集してください。私はそれを修正しましたが、正しい方向に私を向けるためにクレジットを持っていると思います。 – gulbaek

1

試してみてください。

;with CTE as 
(select 0 months_ago union all 
select months_ago - 1 months_ago from CTE where months_ago > -11), 
month_list as 
(select dateadd(MONTH, 
       months_ago, 
       dateadd(DAY, 
         1-datepart(DAY,getdate()), 
         cast(GETDATE() as DATE))) month_start 
from cte) 
SELECT YEAR(ml.start_date) as 'Year', 
     MONTH(ml.start_date) as 'Month', 
     sum(Amount) as 'Units sold',[ProductNo] 
FROM month_list ml 
left join [Order] o 
     on o.OrderDate >= ml.start_date and 
      o.OrderDate < dateadd(MONTH, 1, ml.start_date) 
left join [OrderLine] ol 
     on ol.OrderNo = o.OrderNo and ProductNo = @ProductNo 
Group by ProductNo, YEAR(ml.start_date), Month(ml.start_date) 
Order by ProductNo, YEAR(ml.start_date), Month(ml.start_date) 
関連する問題