Это может выглядеть примерно так:
DECLARE @DateBeg DATE = '2019-01-01'
,@DateEnd DAte = '2020-12-01';
WITH Ranges AS
(
SELECT *
,@DateBeg AS [DateBeg]
,@DateEnd AS [DateEnd]
FROM ItemDefinition DS
)
SELECT *
,DATENAME(MONTH ,ISNULL([GeneratedDate], [RenewalDate])) AS RenewalMonth
FROM Ranges
OUTER APPLY
(
SELECT DATEADD(MONTH, [number], [DateBeg])
FROM
(
select number
from master.dbo.spt_values
where [type] = 'P'
) numbers
WHERE DATEADD(MONTH, [number], [DateBeg]) < [DateEnd]
AND [PaymentPlan] = 'Monthly'
) AutoDates ([GeneratedDate]);
Вы можете изменить параметр DateEnd
на что-то меньшее, и вы увидите, как генерируется меньше месяцев.
Идея состоит в том, чтобыиметь start
и end
дату для каждой строки и в зависимости от нее генерировать свои месяцы.
Чтобы получить записи за годы, используйте следующую команду:
WITH Ranges AS
(
SELECT *
,@DateBeg AS [DateBeg]
,@DateEnd AS [DateEnd]
FROM ItemDefinition DS
)
SELECT *
,DATENAME(MONTH ,ISNULL([GeneratedDate], [RenewalDate])) AS RenewalMonth
,IIF([PaymentPlan] = 'Monthly', [UnitRate], IIF(CONVERT(VARCHAR(7), [RenewalDate], 121) = CONVERT(VARCHAR(7), [GeneratedDate], 121), [UnitRate], NULL))
FROM Ranges
OUTER APPLY
(
SELECT DATEADD(MONTH, [number], [DateBeg])
FROM
(
select number
from master.dbo.spt_values
where [type] = 'P'
) numbers
WHERE DATEADD(MONTH, [number], [DateBeg]) < [DateEnd]
) AutoDates ([GeneratedDate]);
или следующую, чтобы получить годовую ставку для первой записи:
DECLARE @DateBeg DATE = '2019-01-01'
,@DateEnd DAte = '2020-12-01';
WITH Ranges AS
(
SELECT *
,@DateBeg AS [DateBeg]
,@DateEnd AS [DateEnd]
FROM ItemDefinition DS
)
SELECT *
,DATENAME(MONTH ,ISNULL([GeneratedDate], [RenewalDate])) AS RenewalMonth
,IIF([PaymentPlan] = 'Monthly', [UnitRate], IIF([number] = 0, [UnitRate], NULL))
FROM Ranges
OUTER APPLY
(
SELECT DATEADD(MONTH, [number], [DateBeg])
,[number]
FROM
(
select number
from master.dbo.spt_values
where [type] = 'P'
) numbers
WHERE DATEADD(MONTH, [number], [DateBeg]) < [DateEnd]
) AutoDates ([GeneratedDate], [number]);