Конкатенированные диапазоны дат в SQL (предпочтительно T / SQL) - PullRequest
0 голосов
/ 09 сентября 2011

Мне нужно объединить строки с датой и кодом в диапазон дат

Таблица с двумя столбцами, представляющими собой составной первичный ключ (дата и код)

Date        Code  
1/1/2011    A  
1/2/2011    A  
1/3/2011    A  
1/1/2011    B  
1/2/2011    B
2/1/2011    A
2/2/2011    A
2/27/2011   A
2/28/2011   A
3/1/2011    A
3/2/2011    A
3/3/2011    A
3/4/2011    A

Требуетсябыть преобразованным в

Start Date    End Date    Code
1/1/2011      1/3/2011    A
2/1/2011      2/2/2011    A
1/1/2011      1/2/2011    B
2/27/2011     3/4/2011    A

Есть ли какой-либо другой путь или только курсорный цикл?

Ответы [ 3 ]

3 голосов
/ 09 сентября 2011
declare @T table
(
  [Date] date,
  Code char(1)
)

insert into @T values
('1/1/2011','A'),  
('1/2/2011','A'),  
('1/3/2011','A'),  
('1/1/2011','B'),  
('1/2/2011','B'), 
('3/1/2011','A'),
('3/2/2011','A'),
('3/3/2011','A'),
('3/4/2011','A')

;with C as
(
  select *,
         datediff(day, 0, [Date]) - row_number() over(partition by Code 
                                                      order by [Date]) as rn
  from @T
)  
select min([Date]) as StartDate,
       max([Date]) as EndDate,
       Code
from C
group by Code, rn
2 голосов
/ 09 сентября 2011

SQL Server 2000 имеет свои ограничения.Переписал решение, чтобы сделать его более читабельным.

declare @t table 
( 
  [Date] datetime, 
  Code char(1) 
) 

insert into @T values 
('1/1/2011','A'),   
('1/2/2011','A'),   
('1/3/2011','A'),   
('1/1/2011','B'),   
('1/2/2011','B'),  
('3/1/2011','A'), 
('3/2/2011','A'), 
('3/3/2011','A'), 
('3/4/2011','A') 

select a.code, a.date, min(b.date)
from
(
    select *
    from @t t 
    where not exists (select 1 from @t where t.code = code and t.date -1 = date)
) a
join 
(
    select *
    from @t t 
    where not exists (select 1 from @t where t.code = code and t.date  = date -1)
) b
on a.code = b.code and a.date <= b.date
group by a.code, a.date
1 голос
/ 09 сентября 2011

Использование функции DatePart для месяца даст вам «группы», которые вы хотите

SELECT Min(Date) as StartDate, Max(Date) as EndDate, Code 
FROM ThisTable Group By DatePart(m, Date), Code
...