Найти самые перекрытые дни? - PullRequest
5 голосов
/ 01 апреля 2012

Я пытаюсь написать запрос, который будет выдавать:

дата / с, которые перекрываются не более.

формат d/m/yyyy

так вот у меня есть диапазоны дат:

dateStart ----- dateEnd

  1/1---7/1                          

         8/1--15/1                   

               16/1------20/1               

         8/1--------------21/1       

                17/1---19/1 

                 18/1--19/1  

это желаемый результат анализа:

enter image description here

2 обычных дня слева: 8/1 и 9/1 (отображается в 2 диапазонах)

4 обычных дня справа 18/1 и 19/1 (отображаются в 4 диапазонах)... и 4> 2, поэтому он должен победить.)

желаемый результат:

18/1

19/1

они оба выглядят наиболее перекрытыми.

edit

это скрипт диапазонов datetime.

DECLARE @t table( dt1 DATETIME , dt2 DATETIME)

INSERT INTO @t
SELECT '20110101','20110107'
UNION ALL
SELECT '20110108','20110115'
UNION ALL
SELECT '20110116','20110120'
UNION ALL
SELECT '20110108','20110121'
UNION ALL
SELECT '20110117','20110119'
UNION ALL
SELECT '20110118','20110119'

Ответы [ 3 ]

3 голосов
/ 01 апреля 2012

Этот запрос покажет отдельные даты с большинством событий. CTE tableOfDates создает таблицу дат от min (startDate) до max (enddate). Основная часть запроса просто считает интервалы, содержащие этот день. Если вы хотите увидеть полный список, закомментируйте top 1 с галстуками part. Существует версия Sql Fiddle .

; with tableOfDates as (
   select min (startdate) aDate, max(enddate) enddate
     from tbl
   union all
    select aDate + 1, enddate
      from tableOfDates
     where enddate > aDate
)
select top 1 with ties tableOfDates.aDate, count (*)
from tableOfDates
   inner join tbl
      on tableOfDates.aDate >= tbl.startDate
     and tableOfDates.aDate <= tbl.enddate
group by tableOfDates.aDate
order by 2 desc
option (maxrecursion 0)
3 голосов
/ 01 апреля 2012

Боюсь, что это не совсем то, что вы ищете, но, может быть, это все равно вам поможет (у меня заканчивается время):

DECLARE @tbl table( startdate DATETIME , enddate DATETIME)

INSERT INTO @tbl
SELECT '20110101','20110107'
UNION ALL
SELECT '20110108','20110115'
UNION ALL
SELECT '20110116','20110120'
UNION ALL
SELECT '20110108','20110121'
UNION ALL
SELECT '20110117','20110119'
UNION ALL
SELECT '20110118','20110119'

;with overlapping_events as(
    select startdate, enddate
       , (select sum(inTimeSpan) 
    from (
       select case when startdate<=events.startdate then 1 else 0 end
         + case when enddate <= events.startdate then -1 else 0 end as inTimeSpan
       from @tbl 
       where startdate <= events.startdate
         or enddate <= events.startdate) as previous
    ) as overlapping
    from @tbl events
)
select oe.* 
from overlapping_events oe 
order by overlapping desc, startdate asc, enddate asc

startdate                     enddate                     overlapping
2011-01-18 00:00:00.000   2011-01-19 00:00:00.000         4
2011-01-17 00:00:00.000   2011-01-19 00:00:00.000         3
2011-01-08 00:00:00.000   2011-01-15 00:00:00.000         2
2011-01-08 00:00:00.000   2011-01-21 00:00:00.000         2
2011-01-16 00:00:00.000   2011-01-20 00:00:00.000         2
2011-01-01 00:00:00.000   2011-01-07 00:00:00.000         1
0 голосов
/ 01 апреля 2012

Отличный вопрос.

Я бы сделал это к

  • расширение всех диапазонов дат в отдельные / вертикальные записи.
    превратить «20110101», «20110107» в
    '20110101'
    '20110102'
    '20110103'
    '20110104'
    '20110105'
    '20110106'
    '20110107'

  • затем, группируя по отдельным датам и возвращая одну (ие) с максимальным количеством

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...