2013-11-25 2 views
0

В SQL Server у меня есть список простоя. В нем перечислены начальное и конечное значение каждого простоя. Я хочу получить последнюю дату, но каждый день смешивается.SQL Server: Как вы можете превратить серию последовательных начальных и конечных дат в единый начальный диапазон?

Пример:

Мы предполагаем, что каждый простои в тот же день.

A) begin 09:00 End 11:00 
B) begin 10:00 End 12:00 
C) begin 12:00 End 13:00 
D) begin 15:00 End 16:00 

Тестовый пример:

1) 
At - 11:00 
Results: Begin A (9:00), End C (13:00) 

2) 
At - 11:30 
Results: Begin B (10:00), End C (13:00) 

3) 
At - 12:00 
Results: Begin B (10:00), End C (13:00) 

4) 
At - 12:30 
Results: Begin C (10:00), End C (13:00) 

Если мы только посмотрим на значение "End". Его всегда последняя дата, каждая дата смешивалась. его, как и все простоя в одной временной шкале. вы ставите и проверяете, когда закончится простоя. Независимо от того, является ли это простоем A или B или C ....

Примечание: только SQL-запрос, без функции. Я предпочитаю без рекурсивного, но.


От Mack Ответ:

DECLARE @Downtime AS TABLE(beginDT datetime, endDT datetime) 
INSERT INTO @Downtime VALUES('09:00','11:00') 
INSERT INTO @Downtime VALUES('10:00','12:00') 
INSERT INTO @Downtime VALUES('12:00','13:00') 
INSERT INTO @Downtime VALUES('15:00','16:00') 

Я думаю, что нужно рекурсивным. search @DateNow должно быть между beginDT и endDT. и нам нужно проверить рекурсивно, если у endDT каждого из них было другое время простоя.

В моем примере A-B-C являются последовательными (или в то же время). поэтому, если CURRENTTIME между попрошайничеством А и концом С, времени реального Конца есть конец простоя дерева (13:00)

9 10 11 12  13  14  15  16 

|----A----| 

    |----B----| 

       |---C---| 

             |---D---| 


|---- A and B and C ---| 
+1

Привет при х, Вам действительно нужно включать структуры таблицы для нас, чтобы быть в состоянии помочь правильно. Ваш текущий запрос тоже поможет. – Mack

ответ

0

Хорошо, так на основе расширенных данных, вы будете (вероятно) нужна рекурсия:

--test переменных & среды

DECLARE @TimeParam AS DATETIME 
DECLARE @Downtime AS TABLE(ID VARCHAR(1), beginDT datetime, endDT datetime) 
INSERT INTO @Downtime VALUES('a','09:00','11:00') 
INSERT INTO @Downtime VALUES('b','10:00','12:00') 
INSERT INTO @Downtime VALUES('c','12:00','13:00') 
INSERT INTO @Downtime VALUES('d','15:00','16:00') 
INSERT INTO @Downtime VALUES('e','12:00','17:00') 
INSERT INTO @Downtime VALUES('f','15:00','19:00') 
INSERT INTO @Downtime VALUES('g','19:00','20:00') 
INSERT INTO @Downtime VALUES('h','20:00','21:00') 
INSERT INTO @Downtime VALUES('i','21:00','22:00') 
INSERT INTO @Downtime VALUES('j','22:00','23:00') 

SET @TimeParam ='1900-01-01 15:30:00.000' 

--query

DECLARE @Depth as INT --(Use this to control the recursion) 
SET @Depth = 4 
;WITH ConsecutiveDownTimeBase (ID, beginDT, endDT,IsBase) 
AS 
(
SELECT ID 
    , beginDT 
    , endDT 
    , 1 IsBase 
FROM @DownTime dt 
WHERE @TimeParam BETWEEN beginDT AND endDT 
UNION ALL 
-- Recursive member definition 
SELECT a.ID 
    , a.beginDT 
    , a.endDT 
    , b.IsBase+1 
FROM ConsecutiveDownTimeBase AS b 
INNER JOIN @Downtime a 
    ON b.endDT BETWEEN a.beginDT and a.endDT 
    AND b.IsBase<[email protected] 
UNION ALL 
-- Recursive member definition 
SELECT c.ID 
    , c.beginDT 
    , c.endDT 
    , b.IsBase+1 
FROM ConsecutiveDownTimeBase AS b 
INNER JOIN @Downtime c 
    ON b.beginDT BETWEEN c.beginDT and c.endDT 
    AND b.IsBase<[email protected] 
) 
SELECT CONVERT(TIME,MIN(beginDT)) AS beginDT 
    , CONVERT(TIME,MAX(endDT)) AS endDT 
FROM ConsecutiveDownTimeBase 

Вот результаты:

beginDT    endDT 
09:00:00.0000000 23:00:00.0000000 
+0

это только найти время между, я хочу в последний раз. но ваш образец таблицы замечательный. – forX

+0

Могу ли я спросить, кто бы ни проголосовал за этот ответ, чтобы сообщить мне, почему, пожалуйста? Когда я ответил, я летел слепой. – Mack

+0

@forX Я отредактировал ответ на основе вашего пересмотренного вопроса, надеюсь, что это даст вам то, что вам нужно. Как и максимальный конечный диапазон времени, я добавил минимальное время начала на всякий случай, если вам это не нужно, просто удалите столбец dtBefore и RangeStart. – Mack

Смежные вопросы