T- SQL Отменить специальные тарифы и создать окончательный диапазон дат - PullRequest
3 голосов
/ 01 мая 2020

У меня есть таблица транзакций, в которой есть диапазон дат и базовая ставка c для диапазона. У меня есть еще одна таблица для специального курса, который имеет диапазон дат для специального курса и его курс. Я хотел бы разделить мою исходную транзакцию на несколько записей, если специальные ставки попадают в диапазон дат транзакции.

Просто для простоты я создал две таблицы с ограниченными столбцами

DECLARE @ClientTrx AS TABLE (ClientId int, StartDate Date, EndDate Date, Rate decimal(10,2))
DECLARE @SpecialRate AS TABLE (ClientId int, StartDate Date, EndDate Date, Rate decimal(10,2))

insert into @ClientTrx select 1, '1/1/2020', '1/15/2020', 10
insert into @ClientTrx select 1, '1/16/2020', '1/31/2020', 10
insert into @ClientTrx select 2, '1/1/2020', '1/15/2020', 20
insert into @ClientTrx select 2, '1/16/2020', '1/31/2020', 20
insert into @ClientTrx select 2, '2/1/2020', '2/13/2020', 20

insert into @SpecialRate select 1, '12/25/2019', '1/3/2020', 13
insert into @SpecialRate select 1, '1/4/2020', '1/6/2020', 15
insert into @SpecialRate select 1, '1/11/2020', '1/18/2020', 12

insert into @SpecialRate select 2, '1/25/2020', '1/31/2020', 23
insert into @SpecialRate select 2, '2/4/2020', '2/8/2020', 25
insert into @SpecialRate select 2, '2/11/2020', '2/29/2020', 22

Мне нужна помощь в написании запрос, который дает следующие результаты:

ClientId    StartDate   EndDate Rate
1   2020-01-01  2020-01-03  13.00   special rate
1   2020-01-04  2020-01-06  15.00   special rate
1   2020-01-07  2020-01-10  10.00   regular rate
1   2020-01-11  2020-01-15  12.00   special rate
1   2020-01-16  2020-01-18  12.00   special rate splitting pay period
1   2020-01-19  2020-01-31  10.00   regular rate
2   2020-01-01  2020-01-15  20.00   regular rate  
2   2020-01-16  2020-01-24  20.00   regular rate
2   2020-01-25  2020-01-31  23.00   special rate
2   2020-02-01  2020-02-03  20.00   regular rate  
2   2020-02-04  2020-02-08  25.00   special rate
2   2020-02-09  2020-02-10  20.00   regular rate 
2   2020-02-11  2020-02-13  22.00   special rate

Я думаю, что использование CTE возможно, но я не могу понять это. Может кто-нибудь, пожалуйста, помогите?

Примечание: я внес некоторые изменения в свой ввод и ожидаемый результат, я думаю, мне нужен еще один уровень группы, не могли бы вы помочь?

1 Ответ

2 голосов
/ 01 мая 2020

Это подход, который использует и ad-ho c таблицу подсчета для расширения наборов данных, а затем применяет пробелы и острова для окончательной сводки

Пример

;with cte as (
Select A.ClientId
      ,D    
      ,Rate = coalesce(NewRate,A.Rate)
      ,Grp  = datediff(day,'1900-01-01',D) - row_number() over (partition by ClientID,coalesce(NewRate,A.Rate) Order by D)
 From  @ClientTrx A
 Cross Apply ( 
                Select Top (DateDiff(DAY,StartDate,EndDate)+1) D=DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),StartDate) 
                 From  master..spt_values n1,master..spt_values n2 
             ) B
 Outer Apply (
               Select NewRate=Rate 
                 From @SpecialRate
                 Where D between StartDate and EndDate
                   and ClientId=A.ClientID
             ) C
)
Select ClientID
      ,StartDate= min(D)
      ,EndDate  = max(D)
      ,Rate     = Rate
 From  cte
 Group By ClientID,Grp,Rate
 Order by ClientID,min(D)

Возвращает

ClientID    StartDate   EndDate     Rate
1           2020-01-01  2020-01-03  13.00
1           2020-01-04  2020-01-06  15.00
1           2020-01-07  2020-01-10  10.00
1           2020-01-11  2020-01-18  12.00
1           2020-01-19  2020-01-31  10.00
2           2020-01-01  2020-01-24  20.00
2           2020-01-25  2020-01-31  23.00
2           2020-02-01  2020-02-03  20.00
2           2020-02-04  2020-02-08  25.00
2           2020-02-09  2020-02-10  20.00
2           2020-02-11  2020-02-15  22.00

Примечания:

При перекрестном применении B создается запись для каждой даты между startDate и endDate в @ClientTrx.

Outer Apply C пытается найти исключение или NewRate

, CTE генерирует одну запись на дату и переключает значение по умолчанию или частоту исключений. Это выглядит так:

enter image description here

Обратите внимание, как изменяется GRP. Это простая техника, чтобы «кормить» Гапсы и острова

. Затем становится небольшим вопросом сгруппировать результаты из cte по ClientID и Grp

.
...