2012-03-13 2 views
-1

Я использую следующий запрос в линейной диаграмме ssrs. Он подсчитывает, сколько заказов записывается каждый месяц на основе каждой даты заказа.Обработка несуществующих значений в выражении запроса sql для диаграммы ssrs

Моя проблема заключается в том, что, когда у месяца нет заказов, вместо того, чтобы указывать нуль или нуль, он удаляет строку для этого месяца все вместе. Я бы предпочел, чтобы он считал его нулевым, но null тоже было бы в порядке.

В принципе, я хочу, чтобы всегда иметь двенадцать строк, независимо от того, содержит ли они информацию или нет.

Как это исправить? Есть ли выражение, которое я могу использовать или что-то еще? Или я пропущу что-то совершенно очевидное?

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

Понял работает путем удаления, где положение и фильтрация в счетном агрегате.

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) 

Примечание - я добавил дополнительные где условия положение, чтобы проверить на функции года на orddate, так как это может быть пустым

Google для соединений SQL, и я уверен, вы найдете гораздо больше информации, чем качества этого

Надеется, что это помогает

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 (SELECT Month = 1 UNION ALL SELECT 2 UNION ALL SELECT 3 ...) AS Months'? –

+0

Исправить. Но это должна быть ваша таблица «MASTER» ... Итак, начните с того, чтобы потом присоединиться к вашим другим таблицам. –

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-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 строк. И нет необходимости создавать и таблицы.

Смежные вопросы