Получить все даты между двумя последовательными датами в одном столбце для указанной группы c - PullRequest
0 голосов
/ 02 марта 2020

У меня есть таблица рынка (#Market), например:

enter image description here

Для каждой даты поставки рынка мне нужно генерировать даты до следующая дата поставки этого рынка. Желаемый результат должен быть таким, как показано ниже:

enter image description here

Я попытался получить календарные даты, основанные на максимальном и минимальном диапазоне дат для всех рынков, а затем попытался сопоставить даты с рыночными датами доставки.

Календарные даты (#Calendar) генерируются следующим образом:

Date
2020-03-01
2020-03-02
2020-03-03
2020-03-04
2020-03-05
2020-03-06
2020-03-07
2020-03-08
2020-03-09
2020-03-10
2020-03-11
2020-03-12
2020-03-13
2020-03-14
2020-03-15

Но я не смог найти способ сравнить календарную таблицу с таблицу Market и получите даты между последовательными строками для каждой даты поставки и рынка. Приведенное ниже перекрестное соединение дает мне все даты после даты доставки sprcifi c, но не может быть ограничено до следующей даты поставки для этого рынка.

select * from #Calendar c
    cross join #Market  m
    where date>=[Delivery Date]
    order by marketid,[Delivery Date]

Есть ли способ ограничить эти даты непосредственно перед следующая дата поставки для определенного c рынка?

Ответы [ 2 ]

1 голос
/ 02 марта 2020

При условии, что разрыв составляет не более 1000 дней, должно работать следующее

with row_gen
  as (select top 1000 row_number() over(order by name)-1 as rnk
        from master..spt_values
     )
    ,dates
      as(
        select a.marketid,a.delivery_date,case when lead(a.delivery_date) over(partition by marketid order by delivery_date asc) is null then 
                                                    dateadd(day,1,a.delivery_date)
                                               else lead(a.delivery_date) over(partition by marketid order by delivery_date asc) 
                                           end as next_val
          from dbo.t a
         )
select *,dateadd(day,b.rnk,a.delivery_date)
  from dates a
  join row_gen b
    on dateadd(day,b.rnk,a.delivery_date)<a.next_val
1 голос
/ 02 марта 2020

Вы можете использовать рекурсивный CTE:

with cte as (
      select marketid, deliverydate, deliverydate as date,
             dateadd(day, -1, lead(deliverydate) over (partition by marketid order by deliverydate)) as lastdd
      from #market m
      union all
      select marketid, deliverydate, dateadd(day, 1, date) as date,
             lastdd
      from cte
      where date < lastdd
     )
select marketid, deliverydate, date
from cte;

Если вы можете иметь более 100 дней в промежутке, тогда вам понадобится option (maxrecursion 0).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...