Можете ли вы использовать вместо ISNULL, то есть;
SUM(ISNULL(AMOUNT,0)) AMOUNT,
РЕДАКТИРОВАТЬ: хорошо, учитывая, что проблема, кажется, пропускает значения, а не нули как таковые. попробуйте что-нибудь подобное.
Во-первых, создайте постоянную таблицу report_framework. Этот основан на месяцах и годах, но вы могли бы расширить его на дни, если хотите.
</p>
<pre><code>create table reporting_framework
([month] smallint, [year] smallint);
go
declare @year smallint;
declare @month smallint;
set @year=2000;
while @year<2500
begin
set @month=1;
while @month<13
begin
insert into reporting_framework ([month], [year]) values (@month, @year);
set @month=@month+1;
end
set @year=@year+1;
end
select * from reporting_framework;
(это дает вам 6000 строк, от 2000 до 2499 - подстраивайтесь по вкусу!)
Теперь мы составим таблицу деталей и таблицу заказов
create table parts
([part_num] integer, [description] varchar(100));
go
insert into parts (part_num, [description]) values (100, 'Widget');
insert into parts (part_num, [description]) values (101, 'Sprocket');
insert into parts (part_num, [description]) values (102, 'Gizmo');
insert into parts (part_num, [description]) values (103, 'Foobar');
create table orders
([id] integer, part_num integer, cost numeric(10,2), orderdate datetime);
go
insert into orders ([id], part_num, cost, orderdate) values
(1, 100, 49.99, '2011-10-30');
insert into orders ([id], part_num, cost, orderdate) values
(2, 101, 109.99, '2011-10-31');
insert into orders ([id], part_num, cost, orderdate) values
(3, 100, 47.99, '2011-10-31');
insert into orders ([id], part_num, cost, orderdate) values
(4, 102, 429.99, '2011-11-01');
insert into orders ([id], part_num, cost, orderdate) values
(5, 101, 111.17, '2011-11-01');
insert into orders ([id], part_num, cost, orderdate) values
(6, 101, 111.17, '2011-11-01');
insert into orders ([id], part_num, cost, orderdate) values
(7, 103, 21.00, '2011-09-15');
Теперь это таблица, на которой вы основываете свой запрос, например;
select rf.month, rf.year, p.description, sum(isnull(o.cost,0))
from reporting_framework rf cross join parts p
full outer join orders o
on rf.year=year(o.orderdate) and rf.month=month(o.orderdate)
and p.part_num=o.part_num
where rf.year='2011'
group by p.description, rf.month, rf.year
order by rf.year, rf.month, p.description
Этот пример помогает? Вероятно, есть множество более эффективных способов сделать это (привет StackOverflow), но это может заставить вас задуматься о том, в чем ваша проблема.
Не CROSS JOIN, чтобы получить все комбинации деталей / дат, а затем FULL OUTER JOIN, чтобы получить в него заказы.
Предложение where просто контролирует ваш диапазон дат.