2017-02-19 3 views
0

У меня есть набор данных сSQL Person по месяцам Данные

Name|ID|Start_DATE|END_DATE 

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

Пример:

Bob Smith|1001|2016-12-01|2017-02-18 

бы вернуть все месяцы, перечисленные между датами

Bob Smith|1001|2016-12-01 
Bob Smith|1001|2017-01-01 
Bob Smith|1001|2017-02-02 

Я строгания с некоторыми данными, основанными на даты, которые я нашел. Мне также придется иметь дело с активными сотрудниками, указанными как 9999-12-31, когда я выясню базовый запрос.

declare @startDate date; 
declare @endDate date; 

select @startDate = '20100101'; 
select @endDate = '20150531'; 

with dateRange as 
(
    select dt = dateadd(mm, 0, @startDate) 
    where dateadd(mm, 0, @startDate) < @endDate 
    union all 
    select dateadd(mm, 1, dt) 
    from dateRange 
    where dateadd(mm, 1, dt) < @endDate 
) 
select * 
from dateRange 

Есть ли лучший способ справиться с этим?

+0

Это вопрос MySql. Пожалуйста, отметьте его соответствующим образом. Это привлечет более конкретную помощь к вашему вопросу. –

+0

Нет, MS SQL была целевой аудиторией –

+0

Вы спрашиваете, есть ли лучший способ генерации dateRange? –

ответ

0

Предполагая, что я понял вопрос, вот один из способов сделать это:

Во-первых, создание и заполнение таблицы выборки (Пожалуйста сохранить нас этот шаг в ваших будущих вопросов)

DECLARE @T AS TABLE 
(
    Name varchar(20), 
    ID int, 
    Start_DATE date, 
    END_DATE date 
) 
INSERT INTO @T VALUES 
('Bob Smith', 1001, '2016-12-01', '2017-02-18') 

DateRange календарь КТР из вашего вопроса, с датами, что соответствует данной выборке:

declare @startDate date; 
declare @endDate date; 

select @startDate = '20150101'; 
select @endDate = '20200531'; 

with dateRange as 
(
    select dt = dateadd(mm, 0, @startDate) 
    where dateadd(mm, 0, @startDate) < @endDate 
    union all 
    select dateadd(mm, 1, dt) 
    from dateRange 
    where dateadd(mm, 1, dt) < @endDate 
) 

запрос:

SELECT Name, 
     ID, 
     CONVERT(char(12), Start_DATE, 107) As StartDate, -- just to see it clearly in the results 
     CONVERT(char(12), END_DATE, 107) As EndDate, -- just to see it clearly in the results 
     CONVERT(char(12), dt, 107) As ActiveMonth 

FROM @T 
INNER JOIN dateRange ON dt >= Start_DATE AND dt < END_DATE 

Результаты:

Name  ID  StartDate  EndDate   ActiveMonth 
Bob Smith 1001 Dec 01, 2016 Feb 18, 2017 Dec 01, 2016 
Bob Smith 1001 Dec 01, 2016 Feb 18, 2017 Jan 01, 2017 
Bob Smith 1001 Dec 01, 2016 Feb 18, 2017 Feb 01, 2017 

Кстати, есть лучший способ создать календарь КТР, используя таблицу чисел а (или бирку). here a demo.

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