2014-06-11 2 views
1

Недавно я столкнулся с проблемой перекрытия интервалов. У меня следующая ситуация:Перекрывающиеся периоды - Слияние в непрерывных временных рядах

Вход:

У меня есть одна таблица БД, которая содержит ежемесячные данные, как, что:

StartDate | EndDate | Value 

31.07.2010 | 31.08.2010 | 4500 
31.08.2010 | 30.09.2010 | 6500 

И одна таблица, которая содержит от - до данных, как, что:

StartDate | EndDate | Value 

16.08.2010 | 29.09.2010 | 9500 

Выход: Новый стол с непрерывной периодической серией

StartDate | EndDate | Value 

31.07.2010 | 15.08.2010 | 4500 
16.08.2010 | 29.09.2010 | 9500 
30.09.2010 | 30.09.2010 | 6500 

Как вы решите такую ​​проблему?

Моей идеей было бы сделать объединение двух таблиц и отсортировать их по дате начала. Определите периоды перекрытия и отрегулируйте их.

Есть ли уже алгоритм, который я могу использовать для этой цели? Или кто-то подошел к уже подобной проблеме?

Спасибо, Patric

+0

Перенос на dba.stackexchange? Какой сервер-тег? –

ответ

0

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

;with cte(StartDate) as (
    select distinct StartDate from Table1 
    union 
    select distinct EndDate from Table1 
    union 
    select distinct StartDate from Table2 
    union 
    select distinct dateadd(dd, 1, EndDate) from Table2 
), cte2 as (
    select 
     StartDate, 
     row_number() over(order by StartDate asc) as rn 
    from cte 
) 
select 
    c.StartDate, 
    case 
     when c2.rn = max(c2.rn) over() then c2.StartDate 
     else dateadd(dd, -1, c2.StartDate) 
    end as EndDate 
from cte2 as c 
    inner join cte2 as c2 on c2.rn = c.rn + 1 

sql fiddle demo

Этот код для SQL Server, и ответ зависит от того, если это возможно на конец периода, чтобы быть равным началу следующего периода или нет, но вы можете получить общую идею.

+0

@pamaxeed no prob, этот код с CTE может быть не очень быстрым, вы можете использовать некоторую таблицу temp для хранения дат. –

+0

Привет, Роман, Спасибо за ответ, это очень полезно для меня. Просто чтобы понять подход к ur: u создайте временный набор данных (cte, я думаю, что это ключевое слово transact sql), где u хранит все StartDate и заказываю его по возрастанию. И затем сделайте для каждой начальной даты, и получите начальную точку следующей строки и сделайте ее как enddate. Это правильно? Почему вы добавляете select different dateadd (dd, 1, EndDate) из таблицы2? И в результате значение отсутствует. – pamaxeed

Смежные вопросы