Обработка несуществующих значений в выражении запроса sql для диаграммы ssrs - PullRequest
0 голосов
/ 14 марта 2012

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

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

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

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

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)

Ответы [ 6 ]

3 голосов
/ 14 марта 2012

Как уже упоминалось выше, вам понадобится внешнее объединение и какая-то календарная таблица. Это не проверено, но я думаю, что будет работать для вас:

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 голосов
/ 10 апреля 2012
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 рядов. И создавать таблицы тоже не нужно.

0 голосов
/ 06 апреля 2012

Получилось, убрав предложение 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)
0 голосов
/ 14 марта 2012
;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 голосов
/ 14 марта 2012

Вам нужна таблица, содержащая месяцы, чтобы выполнить эту работу (или вы можете использовать хранимую процедуру или, возможно, общее табличное выражение).

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 голосов
/ 14 марта 2012

это поведение хорошо определяется конструкцией 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)

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

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

Надеюсь, это поможет

...