2012-03-13 4 views
-1

ssrs 꺾은 선형 차트에서 다음 쿼리를 사용하고 있습니다. 각 주문 날짜를 기준으로 매월 기록되는 주문 수를 계산합니다.ssrs 차트에 대한 sql 쿼리 식에 존재하지 않는 값 처리

내 문제는 한 달에 주문이 없으면 0이나 null이 아니라 모든 달의 행이 함께 제거된다는 것입니다. 0으로 계산하는 것이 더 좋지만 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 값을 검색하기 위해 (있는 올바른 쪽 따라 또는 오른쪽 조인) 가입 좌측 - 절 상태 확인 어디 추가 첨가 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 조합 선택 2 조합 선택 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

이것은 아이디어를주는 것입니다. 영업 이익도 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 행만 제공됩니다. 그리고 테이블을 만들 필요도 없습니다.

관련 문제