2016-04-30 3 views
2

У меня есть последовательность цифр ниже, и я хочу сделать новую группу чисел каждый раз, когда следующий номер имеет разницу в несколько единиц от предыдущего значения, то есть разрыв непрерывного интервалаРазделение интервалов чисел на группы

Таблица Т

value 
1 
2 
3 
5 
6 
7 
15 
16 
17 
18 

группы должны быть образованы из непрерывного интервала:

min max 
1 3 
5 7 
15 18 

Я пытаюсь номер строки с помощью DENSE_RANK() functi на, как и в примере ниже, тогда я смогу сгруппировать по rankNumber и получить MIN (значение) и MAX (значение), но я не нахожу шаблон для использования в предложении PARTITION BY этой функции

value rankNumber 
1  1 
2  1 
3  1 
5  2 
6  2 
7  2 
15 3 
16 3 
17 3 
18 3 

    WITH T2 AS 
    (
    SELECT value, LEAD(value) OVER(ORDER BY value) as nextValue 
    FROM T 
    ) 

    SELECT value, DENSE_RANK() 
    OVER(PARTITION BY CASE WHEN nextValue - value > 1 THEN 1 ELSE 0 END ORDER BY value) 
    FROM T2 

Код для создания таблицы:

CREATE TABLE t(
    value INT 
); 
INSERT INTO t VALUES 
    (1), (2), (3), (5), (6), (7), (15), (16), (17), (18); 

токовый выход с помощью запроса выше:

value rankNumber 
1  1 
2  2 
3  1 
5  3 
6  4 
7  2 
15 5 
16 6 
17 7 
18 8 
+0

Вы можете быть заинтересованы в [* это ответ на «Решение„Пробелы и острова“с row_number() и DENSE_RANK() *?] (Http: // дБА .stackexchange.com/a/167069/2639) –

ответ

4

Вам нужно придумать какой-нибудь способ, чтобы включить последовательности в соответствующие группы. Я только что узнал этот трюк у другого пользователя прямо здесь. Используя ROW_NUMBER, который проходит через все записи, вы можете вычислить групповой ключ, вычитая value на ту же запись из этого номера строки. Если values являются последовательными, то результат вычитания не будет изменен (отсюда и тот же групповой ключ). В противном случае ключ группы будет подпрыгивать до следующего (меньшего) значения. Каждый раз при прыжке ключ группы будет меньше.

Вот запрос:

select min(value) min, max(value) max 
from (select value, ROW_NUMBER() over (order by value) - value as [key] 
     from t) v 
group by [key] 
order by min 
+2

Это отличный ответ! :) –

+0

@EvaldasBuinauskas да идея очень интересная :) как упоминалось в моем ответе, идея изначально была здесь http://stackoverflow.com/ a/36927721/1679602 (если вас интересует - я только что прочитал этот ответ вчера). –

+0

Для объяснения этого метода вам может быть интересно [* этот ответ на «Решение« Пробелов и островов »с помощью row_number() и dense_rank()? *] (http: //dba.stackexchan ge.com/a/167069/2639) –