Используя таблицу подсчета, это довольно просто.Я держу один в моей системе как молниеносное представление, потому что оно вообще не требует дискового ввода-вывода.Это выглядит удивительно похоже на то, что вы опубликовали вначале.
create View [dbo].[cteTally] as
WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select N from cteTally
GO
Далее нам понадобятся примеры данных.Я сократил это до пары журналов для демонстрации.
declare @dummy_data table
(
JOURNAL_NO int
, START_DATE datetime
, END_DATE datetime
, DURATION_ON_BOOK int
)
insert @dummy_data values
(101388, '20140115', '20170101', 35)
, (101499, '20160114', '20170121', 36)
Теперь нам просто нужно использовать мощь таблицы подсчета с вашими данными.Вот как может выглядеть ваш запрос.Нет необходимости в циклах, просто некоторая базовая математика для дат.
select *
, EachDay = dateadd(day, t.N - 1, d.Start_Date)
, MyDay = t.N
, MyMonth = datediff(month, d.Start_DATE, dateadd(day, t.N - 1, d.Start_Date)) + 1
, MyYear = datepart(year, dateadd(day, t.N - 1, d.Start_Date))
from @dummy_data d
join cteTally t on t.N <= datediff(day, d.START_DATE, d.END_DATE) + 1