Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Пересечение периодов  [new]
rebel25
Member

Откуда:
Сообщений: 98
В таблице #period - периоды календарных лет
В таблице #leave - произвольные периоды - от одного дня до нескольких лет.
Необходимо посчитать количество календарных дней периодов из #leave
приходящихся на каждый календарный год из #period. Периоды в #leave не могут пересекаться.

if object_id('tempdb..#period') IS NOT NULL THEN DROP TABLE #period;
create table #period (fromd datetime,tod datetime);

insert into #period values ('2006-05-10','2007-05-09');
insert into #period values ('2007-05-10','2008-05-09');
insert into #period values ('2008-05-10','2009-05-09');
insert into #period values ('2009-05-10','2010-05-09');
insert into #period values ('2010-05-10','2011-05-09');
insert into #period values ('2011-05-10','2012-05-09');

if object_id('tempdb..#leave') IS NOT NULL THEN DROP TABLE #leave;
create table #leave (fromd datetime,tod datetime);

insert into #leave values ('2007-05-23','2007-10-09')
insert into #leave values ('2007-10-26','2009-01-24')
insert into #leave values ('2009-01-25','2010-05-30')
12 окт 11, 15:28    [11427537]     Ответить | Цитировать Сообщить модератору
 Re: Пересечение периодов  [new]
iljy
Member

Откуда:
Сообщений: 8711
rebel25,

делаете join по условию пересечения интервалов, а потом группировку по годам с суммированием количества дней.
12 окт 11, 15:32    [11427572]     Ответить | Цитировать Сообщить модератору
 Re: Пересечение периодов  [new]
aleks2
Guest
declare @period  table (fromd datetime,tod datetime);

insert into @period values ('20060510','20070509');
insert into @period values ('20070510','20080509');
insert into @period values ('20080510','20090509');
insert into @period values ('20090510','20100509');
insert into @period values ('20100510','20110509');
insert into @period values ('20110510','20120509');

declare @leave table (fromd datetime,tod datetime);

insert into @leave values ('20070523','20071009')
insert into @leave values ('20071026','20090124')
insert into @leave values ('20090125','20100530') 

;with
-- пересечения периодов
intersection as (
select P.* 
	,(select MAX(fromd) FROM (select P.fromd union all select L.fromd) F) fd
	,(select MIN(tod) FROM (select P.tod union all select L.tod) T) td
FROM @period P INNER JOIN @leave L ON L.fromd<=P.tod and P.fromd<=L.tod 
)
-- ну ежели я правильно понял чо те нада
select X.fromd, X.tod, SUM(DATEDIFF(day, fd, td)) days
from intersection X
group by X.fromd, X.tod
12 окт 11, 16:06    [11427997]     Ответить | Цитировать Сообщить модератору
 Re: Пересечение периодов  [new]
rebel25
Member

Откуда:
Сообщений: 98
aleks2,

То что надо, спасибо! Нужно запомнить волшебное слово intersection.
12 окт 11, 16:41    [11428377]     Ответить | Цитировать Сообщить модератору
 Re: Пересечение периодов  [new]
mike909
Member

Откуда:
Сообщений: 662
rebel25,

+ +1
SELECT p.fromd, p.tod, SUM( DATEDIFF(day, d.[fromd], d.[tod]) ) as [SumDays]
FROM @leave as t
inner join @period as p on
      (ISNULL(t.fromd, 0) <= ISNULL(p.tod, '99990101')) 
  and 
      (ISNULL(p.fromd, 0) <= ISNULL(t.tod, '99990101')) 
CROSS APPLY(
  SELECT 
     CASE WHEN t.fromd < p.fromd THEN p.fromd ELSE t.fromd END as [fromd]
    ,CASE WHEN p.tod < t.tod THEN p.tod ELSE t.tod END as [tod] 
) as d
GROUP BY p.fromd, p.tod
12 окт 11, 16:53    [11428515]     Ответить | Цитировать Сообщить модератору
 Re: Пересечение периодов  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
rebel25
aleks2,

То что надо, спасибо! Нужно запомнить волшебное слово intersection.
Зачем?
Напишите вместо этого волшебного слова любую букву алфавита или слово из трёх букв!
Что, перестало работать?
12 окт 11, 17:02    [11428611]     Ответить | Цитировать Сообщить модератору
 Re: Пересечение периодов  [new]
rebel25
Member

Откуда:
Сообщений: 98
iap,

)))
12 окт 11, 17:20    [11428768]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить