Выбирайте диапазоны (min, max) только для последовательности чисел +1 - PullRequest
0 голосов
/ 26 декабря 2018

Выбор диапазонов (мин., Макс.) Только для последовательности чисел + 1

Есть таблица:

col_number
1
2
3
4
9
10
12

Необходимо получить данные так:

min   max
1     4
9     10
12    12

Ответы [ 4 ]

0 голосов
/ 27 декабря 2018

В Oracle версии 12.1 или новее вы можете использовать match_recognize примерно так:

with
  my_table(col_number) as (
    select  1 from dual union all
    select  2 from dual union all
    select  3 from dual union all
    select  4 from dual union all
    select  9 from dual union all
    select 10 from dual union all
    select 12 from dual
  )
-- end of sample data (for testing only, not part of the solution)
select min_number, max_number
from   my_table
match_recognize(
  order by col_number
  measures first(col_number) as min_number, last(col_number) as max_number
  pattern  (a b*)
  define b as col_number = prev(col_number) + 1
);

MIN_NUMBER MAX_NUMBER
---------- ----------
         1          4
         9         10
        12         12
0 голосов
/ 26 декабря 2018

В Oracle вы можете сделать это без оконных функций:

select min(col) as "min", max(col) as "max"
from (select t.*, rownum as seqnum
      from (select t.* from t order by col) t
     ) t
group by (col - seqnum)
order by min(col)
0 голосов
/ 27 декабря 2018

Без оконных функций:

WITH 
nmin AS (
  SELECT col_number FROM numbers t WHERE NOT EXISTS 
    (SELECT col_number FROM numbers WHERE numbers.col_number = t.col_number - 1)),
nmax AS (
  SELECT col_number FROM numbers t WHERE NOT EXISTS 
    (SELECT col_number FROM numbers WHERE numbers.col_number = t.col_number + 1))
SELECT 
  nmin.col_number minnumber, 
  (SELECT MIN(nmax.col_number) FROM nmax WHERE nmax.col_number >= nmin.col_number) maxnumber
FROM nmin
ORDER BY nmin.col_number;
0 голосов
/ 26 декабря 2018

Это называется проблемой пробелов и островков.Вы решаете это, вычитая номер строки из значения, чтобы получить групповые ключи:

select min(col), max(col)
from
(
  select
    col,
    col - row_number() over (order by col) as grp
  from mytable
) 
group by grp
order by min(col);
...