T-SQL - интервал времени с перекрытием столбцов даты и времени - PullRequest
0 голосов
/ 09 мая 2018

Я хочу, чтобы максимальный период диапазона дат перекрывал друг друга, и если период не конфликтует с другими диапазонами дат, я хочу, чтобы он был таким, какой он есть.

У меня есть эта таблица:

CREATE TABLE [dbo].[table1]
(
    [id] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
    [StartDate] [datetime] NOT NULL,
    [EndDate] [datetime] NOT NULL
)

и их соответствующие значения:

INSERT INTO [dbo].[table1]  
VALUES (CAST('2013-11-01 00:00:00.000' AS DateTime), CAST('2013-11-10 00:00:00.000' AS DateTime)),
       (CAST('2013-11-05 00:00:00.000' AS DateTime), CAST('2013-11-15 00:00:00.000' AS DateTime)),
       (CAST('2013-11-10 00:00:00.000' AS DateTime), CAST('2013-11-15 00:00:00.000' AS DateTime)),
       (CAST('2013-11-10 00:00:00.000' AS DateTime), CAST('2013-11-25 00:00:00.000' AS DateTime)),
       (CAST('2013-11-26 00:00:00.000' AS DateTime), CAST('2013-11-29 00:00:00.000' AS DateTime))

И ожидаемый результат:

ID    StartDate                  EndDate
--------------------------------------------------------
1     2013-11-01 00:00:00.000    2013-11-25 00:00:00.000
2     2013-11-26 00:00:00.000    2013-11-29 00:00:00.000

Заранее спасибо.

// Редактировать 1: Спасибо.

Работает, но есть новый вопрос для перерывов в той же таблице

INSERT INTO [dbo].[table1]  
VALUES (CAST('2018-05-03 08:30:00.000' AS DateTime), CAST('2018-05-03 08:45:00.000' AS DateTime)),
       (CAST('2018-05-03 08:45:00.000' AS DateTime), CAST('2018-05-03 09:30:00.000' AS DateTime)),
       (CAST('2018-05-03 08:45:00.000' AS DateTime), CAST('2018-05-03 11:30:00.000' AS DateTime)),
       (CAST('2018-05-03 12:45:00.000' AS DateTime), CAST('2018-05-03 13:00:00.000' AS DateTime)),
       (CAST('2018-05-03 14:00:00.000' AS DateTime), CAST('2018-05-03 15:45:00.000' AS DateTime)),
       (CAST('2018-05-03 14:15:00.000' AS DateTime), CAST('2018-05-03 15:30:00.000' AS DateTime))

И ожидаемый результат:

ID    StartDate                  EndDate
--------------------------------------------------------
1     2018-05-03 08:30:00.000    2018-05-03 11:30:00.000
2     2018-05-03 12:45:00.000    2018-05-03 13:00:00.000
3     2018-05-03 14:00:00.000    2018-05-03 15:45:00.000

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Очень похожий ответ, но с использованием индекса и оконных функций, чтобы сделать анализ разрывов и островков более дешевым (более быстрым).

http://sqlfiddle.com/#!18/f19569/3

SELECT
  ROW_NUMBER() OVER (ORDER BY MIN(StartDate)),
  MIN(StartDate),
  MAX(EndDate)
from
(
  SELECT
    *,
    SUM(CASE WHEN PrecedingEndDate >= StartDate THEN 0 ELSE 1 END)
      OVER (ORDER BY StartDate, EndDate)
        AS GroupID
  FROM
  (
    SELECT
      *,
      MAX(EndDate)
        OVER (ORDER BY StartDate, EndDate
                  ROWS BETWEEN UNBOUNDED PRECEDING
                           AND 1 PRECEDING
             )
               AS PrecedingEndDate
    FROM
      Table1
  )
    look_back
)
  grouped
GROUP BY
  GroupID
0 голосов
/ 09 мая 2018

Это форма проблемы разрывов и островков.

В этом случае exists и совокупная сумма и group by являются путем к решению:

select row_number() over (order by min(startdate)),
       min(startdate), max(enddate)
from (select t1.*, sum(isstart) over (order by startdate) as grp
      from (select t1.*,
                   (case when exists (select 1
                                      from table1 tt1
                                      where tt1.startdate <= t1.enddate and tt1.enddate >= t1.startdate and tt1.id <> t1.id
                                     )
                         then 0 else 1
                    end) as isstart
            from table1 t1
           ) t1
     ) t1
group by grp;
...