Создайте новые диапазоны дат из перекрывающихся диапазонов дат и назначьте идентификатор

У меня есть следующая таблица

ID  | START_DATE | END_DATE   | FEATURE
---------------------------------------
001 | 1995-08-01 | 1997-12-31 | 1
001 | 1998-01-01 | 2017-03-31 | 4
001 | 2000-06-14 | 2017-03-31 | 5
001 | 2013-04-01 | 2017-03-31 | 8
002 | 1929-10-01 | 2006-05-25 | 1
002 | 2006-05-26 | 2016-11-10 | 4
002 | 2006-05-26 | 2016-11-10 | 7
002 | 2013-04-01 | 2016-11-10 | 8

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

Больше всего мне нужна помощь в консолидации столбца «функция», которая будет объединять каждую функцию в формат ниже.

ID  | START_DATE | END_DATE   | FEATURE
---------------------------------------
001 | 1995-08-01 | 1997-12-31 | 1
001 | 1998-01-01 | 2000-06-13 | 4
001 | 2000-06-14 | 2013-03-31 | 45
001 | 2013-04-01 | 2017-03-31 | 458
002 | 1929-10-01 | 2006-05-25 | 1
002 | 2006-05-26 | 2013-03-31 | 47
002 | 2013-04-01 | 2016-11-10 | 478

Я использовал следующее для создания тестовых данных.

CREATE TABLE #TEST (
    [ID] [varchar](10) NULL,
    [START_DATE] [date] NULL,
    [END_DATE] [date] NULL,
    [FEATURE] [int] NOT NULL
) ON [PRIMARY]
GO


INSERT INTO #TEST

VALUES

('001','1998-01-01','2017-03-31',4),
('001','2000-06-14','2017-03-31',5),
('001','2013-04-01','2017-03-31',8),
('001','1995-08-01','1997-12-31',1),
('002','2006-05-26','2016-11-10',4),
('002','2006-05-26','2016-11-10',7),
('002','2013-04-01','2016-11-10',8),
('002','1929-10-01','2006-05-25',1)

Какая у вас база данных?

M. Kanarkowski 30.05.2019 18:38

Привет, ребята, я использую SQL Server 2017.

SQL_Novice 31.05.2019 11:53
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
2
60
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вот запрос, который установит DATE_END. Похоже, вы используете SQL Server, но без каких-либо модификаций или с небольшими изменениями он будет работать почти на каждой базе данных.

with grouped_data as
(
    select ID, START_DATE, END_DATE from #TEST group by ID, START_DATE, END_DATE
) 
,cte as
(
    select 
        *,
        ROW_NUMBER() over (partition by ID order by start_date) as nr
    from grouped_data
)
select 
     c1.ID
    ,c1.START_DATE
    ,case when c1.nr <> 1 then isnull(DATEADD(DAY, -1, c2.START_DATE), c1.END_DATE) ELSE c1.END_DATE end as END_DATE  
from cte as c1
left join cte as c2
    on c1.ID = c2.ID
    and c1.nr = c2.nr -1
order by c1.ID

Если у вас есть SQL Server 2017, вы можете легко трансформировать FEATURE с помощью STRING_AGG.

А если ('001','2013-04-01','2017-03-15',8)?

Serg 30.05.2019 19:11

Вы знаете, вы можете легко сломать каждый выбор с помощью других тестовых данных. Он работает для предоставленных данных.

M. Kanarkowski 30.05.2019 19:21
Ответ принят как подходящий

Вы можете использовать apply:

select distinct t.id, t.START_DATE, t.END_DATE, coalesce(tt.feature, t.feature) as feature
from #test t outer apply
     ( select ' '+t1.feature
       from #test t1 
       where t1.id = t.id and t1.end_date = t.end_date and t1.start_date <= t.start_date
       order by t1.start_date
       for xml path('')
     ) tt(feature)
order by t.id, t.START_DATE;

Вот дб <> рабочий пример.

Спасибо, это сработало отлично, чтобы получить функции.

SQL_Novice 31.05.2019 14:44

Другие вопросы по теме