Задача на сообразительность. Я в ступоре!

2king2
Дата: 15.06.2011 21:08:20
Есть таблица с натуральными числами. Нужно написать запрос выбирающий данные о всех числах в виде двух колонок.
1) начало интервала пропущенными числами
2) конец интервала

Должно получится что то такое

Исходная таблица        Таблица которая должна получится
+-------+			+-------+-------+
|  1	|			|  2	|  2	|
|  3	|			|  5	|  6	|
|  4	|			|  9	|  11	|
|  7	|			+-------+-------+
|  8	|
|  12	|
+-------+	

У меня не получилось что то внятное сделать, и я дал ответ что это не реально. Интересно ваше мнение, идеи реализации.
invm
Дата: 15.06.2011 21:22:50
declare @t table (n int)

insert into @t
values
 (1), (3), (4), (7), (8), (12)

select
 t.n + 1, x.n - 1
from
 @t t cross apply
 (select top (1) n from @t where n > t.n order by n) as x
where
 x.n - t.n > 1
iap
Дата: 15.06.2011 21:53:07
invm
declare @t table (n int)

insert into @t
values
 (1), (3), (4), (7), (8), (12)

select
 t.n + 1, x.n - 1
from
 @t t cross apply
 (select top (1) n from @t where n > t.n order by n) as x
where
 x.n - t.n > 1
А так?
declare @t table (n int)

insert into @t
values
 (2), (3), (4), (7), (8), (12)

select
 t.n + 1, x.n - 1
from
 @t t cross apply
 (select top (1) n from @t where n > t.n order by n) as x
where
 x.n - t.n > 1
invm
Дата: 15.06.2011 22:01:02
iap,

А что не так?
sql-ex.ru :)
Дата: 16.06.2011 11:07:15
CREATE TABLE Test (ID INT PRIMARY KEY )

INSERT INTO Test

SELECT 1 id
UNION SELECT 3
UNION SELECT 4
UNION SELECT 7
UNION SELECT 8
UNION SELECT 12


SELECT a.id +1 [begin], b.id -1 [end] FROM test a
LEFT JOIN test b ON a.id<b.id
LEFT JOIN test c ON c.id> a.id AND c.id <b.id
WHERE c.id IS NULL AND b.id -a.id >1
sql-ex.ru :)
Дата: 16.06.2011 11:08:58
begin end
----------- -----------
2 2
5 6
9 11
iap
Дата: 16.06.2011 11:37:19
invm
iap,

А что не так?
1 - 1 должно получиться? 1 пропущена? Или нет?
invm
Дата: 16.06.2011 11:45:07
iap,

Ну единицу добавить несложно, но по условию задачи вроде как не требуется. Но если добавлять начальный с 1, то надо бы добавить и конечный до maxint :)
Начинающий SQL 2008
Дата: 16.06.2011 12:34:46
invm,
Хороший алгоритм, возьму к себе в копилку знаний.
А у меня получилось нечто монструозное
declare @t table (n int)

insert into @t values (1), (3), (4), (7), (8), (12)

;with cte as
(
 select min(n) [mn], max(n) [mx] from @t
 union all
 select [mn] + 1, [mx] from cte
 where mn < mx
)
select min(mn), max(mn) from
(
 select mn, mn - row_number() over (order by (select 0)) [gr]
 from cte
 where not exists (select 1 from @t t where t.n = cte.mn)
) tmp
group by gr
Валдай
Дата: 16.06.2011 16:05:36
MSSQL >= 2005
Одно чтение таблицы

SELECT
 [begin],
 [end]
FROM 
(
  SELECT --R, 
    [begin] = MAX(CASE WHEN W=1 THEN ID END) + 1,
    [end]   = MAX(CASE WHEN W=0 THEN ID END) - 1
  FROM
  (
    SELECT *, R=DENSE_RANK()OVER(PARTITION BY W ORDER BY id)
    FROM
    (
      SELECT *, W=ROW_NUMBER()OVER(ORDER BY id)%2
      FROM #Test
    )x
  )y
  GROUP BY R
)z
WHERE  [begin] <= [end]