Вы можете сделать это относительно простым способом, создав таблицу периодов, которую вы можете объединить с таблицей счетов, чтобы создать по одной строке на учетную запись за период.
Вот пример. Давайте настроим несколько временных таблиц:
create table #balance (
id int identity,
balance float,
date datetime,
aid int
)
create table #period (
id int identity,
startdt datetime,
enddt datetime
)
Введите некоторые тестовые данные:
insert into #yourtable (balance, date, aid) values (4,'2009-01-01',1)
insert into #yourtable (balance, date, aid) values (5,'2009-01-10',1)
insert into #yourtable (balance, date, aid) values (6,'2009-01-10',1)
insert into #yourtable (balance, date, aid) values (7,'2009-01-16',1)
insert into #yourtable (balance, date, aid) values (2,'2009-01-01',2)
insert into #yourtable (balance, date, aid) values (3,'2009-01-10',2)
insert into #yourtable (balance, date, aid) values (4,'2009-01-10',2)
insert into #yourtable (balance, date, aid) values (5,'2009-01-16',2)
insert into #period (startdt, enddt) values ('2009-01-01','2009-01-06')
insert into #period (startdt, enddt) values ('2009-01-06','2009-01-11')
insert into #period (startdt, enddt) values ('2009-01-11','2009-01-16')
insert into #period (startdt, enddt) values ('2009-01-16','2009-01-21')
Теперь давайте запросим все периоды:
from #period p
Добавить по одной строке для каждого баланса до конца периода:
left join #balance b1 on
b1.date <= p.enddt
Поиск сальдо между сальдо первого соединения и концом периода:
left join #balance b2 on
b2.aid = b1.aid
and b1.id < b2.id
and b2.date <= p.enddt
Затем отфильтруйте строки, которые не являются последними сальдо за их период.
where
b2.aid is null
Соединение b2 в основном ищет промежуточное значение, и, говоря, что его идентификатор равен нулю, вы говорите, что промежуточной строки не существует. Окончательный запрос выглядит так:
select
b1.aid
, p.startdt
, b1.balance
from #period p
left join #balance b1 on
b1.date <= p.enddt
left join #balance b2 on
b2.aid = b1.aid
and b1.id < b2.id
and b2.date <= p.enddt
where
b2.aid is null
order by b1.aid, p.startdt
Примечание: запросы предполагают, что баланс с более поздней датой всегда имеет больший идентификатор. Если вам никогда не нужно балансировать с точно такой же датой окончания, вы можете заменить «b1.id