2013-06-11 4 views
7

У меня есть таблица со следующим определениемКак найти границы групп непрерывных последовательных чисел?

CREATE TABLE mytable 
    (
    id  INT IDENTITY(1, 1) PRIMARY KEY, 
    number BIGINT, 
    status INT 
) 

и примеры данных

INSERT INTO mytable 
VALUES (100,0), 
     (101,0), 
     (102,0), 
     (103,0), 
     (104,1), 
     (105,1), 
     (106,0), 
     (107,0), 
     (1014,0), 
     (1015,0), 
     (1016,1), 
     (1017,0) 

Глядя только в строках, где status = 0 как я могу свернуть Number значения в диапазоне смежных последовательных чисел и найти начало и конец каждого диапазона?

т.е. для примера данные результаты будут

  FROM  to 
Number 100  103 
Number 106  107 
Number 1014  1015 
Number 1017  1017 
+0

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

+3

google для «sql server gap и island» – OzrenTkalcecKrznaric

+0

извините, я не могу его найти. –

ответ

25

Как уже упоминалось в комментариях это классический пробелы и островки проблема.

Решение, популяризированное Itzik Ben Gan, должно использовать тот факт, что ROW_NUMBER() OVER (ORDER BY number) - number остается постоянным в пределах «острова» и не может появляться на нескольких островах.

WITH T 
    AS (SELECT ROW_NUMBER() OVER (ORDER BY number) - number AS Grp, 
       number 
     FROM mytable 
     WHERE status = 0) 
SELECT MIN(number) AS [From], 
     MAX(number) AS [To] 
FROM T 
GROUP BY Grp 
ORDER BY MIN(number) 

NB: Если number не гарантировано быть уникальным заменить ROW_NUMBER с DENSE_RANK в приведенном выше коде.

+0

+1: Да, это лучший подход. Никаких проклятых курсоров или неэффективной рекурсии. – RBarryYoung

+0

Ваш гениальный человек! Большое спасибо –

+3

Вот одно из мест, о котором Ицак говорит об этом: http://www.sqlmag.com/article/tsql3/calculating-concurrent-sessions-part-3. Я не буду упоминать, кого он называет, решая его (помимо Бен Фланагана и Арнольда Фримбла). ;-) – RBarryYoung

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