2012-03-13 7 views
-1

ssrs折れ線グラフで次のクエリを使用しています。各注文日に基づいて毎月記録される注文の数をカウントします。ssrsグラフのsqlクエリ式に存在しない値を処理する

私の問題は、月に何も注文がない場合、ゼロまたはヌルというよりも、その月の行をまとめて削除することです。私はゼロとしてそれを数えることを好むだろうが、nullも大丈夫だろう。

基本的には、情報が含まれているかどうかにかかわらず、常に12行が必要です。

どうすればこの問題を解決できますか?私は何か使える表現がありますか?あるいは、私は完全に明白な何かを逃しています

SELECT 
MONTH(Ord.OrdDate) AS 'MONTH', 
COUNT(CASE WHEN @Worker_ID1 IS NULL OR @Worker_ID1 = Worker.ID THEN 1 END) AS 'Worker1', 
COUNT(CASE WHEN @Worker_ID2 IS NULL OR @Worker_ID2 = Worker.ID THEN 1 END) AS 'Worker2', 
COUNT(CASE WHEN @Worker_ID3 IS NULL OR @Worker_ID3 = Worker.ID THEN 1 END) AS 'Worker3', 
COUNT(CASE WHEN @Worker_ID4 IS NULL OR @Worker_ID4 = Worker.ID THEN 1 END) AS 'Worker4', 
COUNT(CASE WHEN @Worker_ID5 IS NULL OR @Worker_ID5 = Worker.ID THEN 1 END) AS 'Worker5' 

FROM Ord 
JOIN Prod ON Ord.Prod_ID = Prod.ID 
JOIN ProdType ON Prod.ProdType_ID = ProdType.ID 
JOIN Grouping ON Ord.Grouping_ID = Grouping.ID 
JOIN Worker ON Grouping.Worker_ID = Worker.ID 

WHERE @Year = YEAR(Ord.OrdDate) 
AND (@ProdType_ID IS NULL OR @ProdType_ID = ProdType.ID) 

GROUP BY MONTH(Ord.OrdDate) 
+0

これは厳密な答えではないので、私はコメントを使用します。 MONTH(Ord.OrdDate)とWorker.IDでグループ化し、ssrs-2008で提供されているピボット・テーブル(正しくリコールするとマトリックス・レポート)を使用することを検討してください。述語をAND Worker.ID IN(\ @ Worker_ID1、\ @ Worker_ID2、\ @ Worker_ID3、\ @ Worker_ID4、\ @ Worker_ID5)。いずれかがNULLの場合、IN句から暗黙的に除外されます。 – Griffin

答えて

0

それはカウント集計にWHERE句やフィルタリングを除去することにより、作業手に入れました。

SELECT 
MONTH(Ord.OrdDate) AS 'MONTH', 
COUNT(CASE WHEN @Year = YEAR(Ord.OrdDate) AND Worker.ID = @Worker_ID1 AND @ProdType_ID = ProdType.ID THEN 1 END) AS 'Worker1', 
COUNT(CASE WHEN @Year = YEAR(Ord.OrdDate) AND Worker.ID = @Worker_ID2 AND @ProdType_ID = ProdType.ID THEN 1 END) AS 'Worker2', 
COUNT(CASE WHEN @Year = YEAR(Ord.OrdDate) AND Worker.ID = @Worker_ID3 AND @ProdType_ID = ProdType.ID THEN 1 END) AS 'Worker3', 
COUNT(CASE WHEN @Year = YEAR(Ord.OrdDate) AND Worker.ID = @Worker_ID4 AND @ProdType_ID = ProdType.ID THEN 1 END) AS 'Worker4', 
COUNT(CASE WHEN @Year = YEAR(Ord.OrdDate) AND Worker.ID = @Worker_ID5 AND @ProdType_ID = ProdType.ID THEN 1 END) AS 'Worker5' 

FROM Ord 
JOIN Grouping ON Ord.Grouping_ID = Grouping.ID 
JOIN Worker ON Grouping.Worker_ID = Worker.ID 
JOIN Prod ON Ord.Prod_ID = Prod.ID 
JOIN ProdType ON Prod.ProdType_ID = ProdType.ID 

GROUP BY MONTH(Ord.OrdDate) 
-1

この動作は、SQL構文 "内部結合"によって明確に定義されています。 使用は、結合条件は、以下のように満たさない場合

SELECT 
MONTH(Ord.OrdDate) AS 'MONTH', 
COUNT(CASE WHEN @Worker_ID1 IS NULL OR @Worker_ID1 = Worker.ID THEN 1 END) AS 'Worker1', 
COUNT(CASE WHEN @Worker_ID2 IS NULL OR @Worker_ID2 = Worker.ID THEN 1 END) AS 'Worker2', 
COUNT(CASE WHEN @Worker_ID3 IS NULL OR @Worker_ID3 = Worker.ID THEN 1 END) AS 'Worker3', 
COUNT(CASE WHEN @Worker_ID4 IS NULL OR @Worker_ID4 = Worker.ID THEN 1 END) AS 'Worker4', 
COUNT(CASE WHEN @Worker_ID5 IS NULL OR @Worker_ID5 = Worker.ID THEN 1 END) AS 'Worker5' 

FROM Prod 
LEFT JOIN ORD ON Ord.Prod_ID = Prod.ID 
JOIN ProdType ON Prod.ProdType_ID = ProdType.ID 
JOIN Grouping ON Ord.Grouping_ID = Groupord.ID 
JOIN Worker ON Grouping.Worker_ID = Worker.ID 

WHERE ((Ord.OrdDate is not null and @Year = YEAR(Ord.OrdDate)) or ORD.prod_id is null) 
AND (@ProdType_ID IS NULL OR @ProdType_ID = ProdType.ID) 

GROUP BY MONTH(Ord.OrdDate) 

(試験せず)NULL値を取得する(これによっては正しい側であり、右結合)に参加注左 - 私は、where句の条件をチェックするために、追加の添加しましたSQLを結合し、この

希望よりもはるかに多くの品質情報を見つけると確信していますためorddateの年間の機能にこれがnull

グーグルことができるように、この

0

あなたが含むテーブルを必要とすることができます(またはストアドプロシージャまたはおそらく共通のテーブル式を使用することができます)。

SELECT Months.Month, COUNT(Orders.OrderID) 
FROM 
Months 
LEFT OUTER JOIN 
Orders 
ON 
MONTH(Orders.OrderDate) = Months.Month 

は、あなたが得たことを確認します:上述の答えとして

Month, Count 
1, 1 
2, 1 
3, 2 
4, NULL 
etc 
+0

これは動作することがわかります。ただし、新しいテーブルやストアドプロシージャを作成する権限はありません。すべてがクエリ内にある必要があります。 – Beninja2

+0

それで 'JOIN(月選択= 1 UNION ALL SELECT 2 UNION ALL SELECT 3 ...)月間? –

+0

正しい。しかし、それはあなたの "マスター"テーブルにする必要があります...それでは、その後、残りのあなたの他のテーブルに参加する –

3

を、あなたは、外部結合とカレンダーのテーブルのいくつかの種類が必要になります。これはテストされていないですが、私はあなたのために働くだろうと思う:

with dateCTE as 
(
    select cast('2012-01-01' as datetime) dateValue -- start date 
    union all 
    select DateAdd(mm, 1, dateValue) 
    from dateCTE 
    where dateValue < '2012-12-30' -- end date 
) 
SELECT 
MONTH(dateCTE.dateValue) AS 'MONTH', 
COUNT(CASE WHEN @Worker_ID1 IS NULL OR @Worker_ID1 = Worker.ID THEN 1 END) AS 'Worker1', 
COUNT(CASE WHEN @Worker_ID2 IS NULL OR @Worker_ID2 = Worker.ID THEN 1 END) AS 'Worker2', 
COUNT(CASE WHEN @Worker_ID3 IS NULL OR @Worker_ID3 = Worker.ID THEN 1 END) AS 'Worker3', 
COUNT(CASE WHEN @Worker_ID4 IS NULL OR @Worker_ID4 = Worker.ID THEN 1 END) AS 'Worker4', 
COUNT(CASE WHEN @Worker_ID5 IS NULL OR @Worker_ID5 = Worker.ID THEN 1 END) AS 'Worker5' 

FROM dateCTE 
LEFT JOIN Ord on MONTH(dateCTE.datevalue) = MONTH(Ord.OrdDate) 
JOIN Prod ON Ord.Prod_ID = Prod.ID 
JOIN ProdType ON Prod.ProdType_ID = ProdType.ID 
JOIN Groupord ON Ord.Groupord_ID = Groupord.ID 
JOIN Worker ON Groupord.Worker_ID = Worker.ID 

WHERE (@Year = YEAR(Ord.OrdDate) or ORD.prod_id is null) 
AND (@DrugType_ID IS NULL OR @ProdType_ID = ProdType.ID) 

GROUP BY MONTH(dateCTE.dateValue) 
OPTION (MAXRECURSION 0) 
+0

+1 CTEは、オンザフライで日付または番号表を生成するのに最適です。 –

+0

@JamieFこれは、特定の年にハードコードされていますが、それはちょっとしたものです。例えば、 'SET LANGUAGE FRENCH'と言うと、日付形式が失敗し、CTEが余分な月を返した場合(CTEを単独で実行すると、13ヶ月間)、その他いくつかの問題があります。 –

+0

これは本当にアイデアを与えることでした。 OPは1年だけの結果をフィルタリングするようにも見え、グループは月ごとであるため、1〜12ヶ月がCTE内にある限り、同じグループを取得します。 – Colin

0
;WITH m(m) AS (SELECT TOP 12 ROW_NUMBER() OVER (ORDER BY [object_id]) FROM sys.objects) 
SELECT [MONTH] = m.m, 
    Worker1 = COUNT(CASE WHEN COALESCE(@Worker_ID1, w.ID) = w.ID THEN 1 END), 
    Worker2 = COUNT(CASE WHEN COALESCE(@Worker_ID2, w.ID) = w.ID THEN 1 END), 
    Worker3 = COUNT(CASE WHEN COALESCE(@Worker_ID3, w.ID) = w.ID THEN 1 END), 
    Worker4 = COUNT(CASE WHEN COALESCE(@Worker_ID4, w.ID) = w.ID THEN 1 END), 
    Worker5 = COUNT(CASE WHEN COALESCE(@Worker_ID5, w.ID) = w.ID THEN 1 END) 
FROM m 
LEFT OUTER JOIN dbo.Ord AS o 
ON o.OrdDate >= DATEADD(MONTH, m.m-1, RTRIM(@Year)+'0101') 
AND o.OrdDate < DATEADD(MONTH, m.m, RTRIM(@Year+'0101') 
INNER JOIN dbo.Prod  AS p ON o.Prod_ID  = p.ID 
INNER JOIN dbo.ProdType AS pt ON p.ProdType_ID = pt.ID 
INNER JOIN dbo.Grouping AS g ON o.Grouping_ID = g.ID 
INNER JOIN dbo.Worker AS w ON g.Worker_ID = w.ID 
WHERE (@DrugType_ID IS NULL OR pt.ID = @ProdType_ID) 
GROUP BY m.m 
ORDER BY m.m; 
0
select a.mon,b.* from 
(
select 1 as mon union select 2 as mon union select 3 as mon union select 4 as mon union 
select 5 as mon union select 6 as mon union select 7 as mon union select 8 as mon union 
select 9 as mon union select 10 as mon union select 11 as mon union select 12 as mon 
) a 
left outer join 
(
    your existing query here 
) b 
on a.mon=b.MONTH(OrdDate) 
go 

ただコピーして、プレースホルダにクエリを貼り付けて行きます。 常に12行しか取得できません。また、テーブルを作成する必要もありません。

関連する問題