2013-10-09 4 views
3

Этот запрос возвращает следующие результаты ...Oracle SQL - набор последовательных чисел в диапазоне

WITH t(wk, COST) AS 
(SELECT wk, COST FROM myTable WHERE id = '345') 
SELECT listagg(wk,',') WITHIN GROUP(ORDER BY wk) AS wks, COST 
FROM t 
GROUP BY COST; 

...

WKS    COST 
---------------------- 
17, 18, 19, 21 446 
26, 27, 28  588 

Можно создать следующие результаты, где последовательные недели являются возвращен как с, так и с. (Например, 1-10, а не 1, 2, 3, 4, ... и т.д.)

WKS    COST 
---------------------- 
17-19, 21   446 
26-28    588 
+1

не должна ли вторая строка быть «26 -28»? –

+0

Хорошее место! Я изменю это ... – Tom

ответ

3

В этой задаче вы должны определить последовательность последовательных недель и сгруппировать их. Вот мое решение.

  • Используйте функцию LAG для идентификации любых разрывов в последовательности.
  • Используйте функцию SUM, чтобы назначить номер группы для каждой последовательности.
  • Найдите начальную и конечную неделю в каждой группе.
  • Наконец, используйте функцию LISTAGG для агрегирования результата.

Запрос:

with x(wk, cost, startgroup) as(
    --identify the start of a sequence 
    select wk, cost, 
      case when wk = lag(wk,1) over (partition by cost order by wk) + 1 
       then 0 
       else 1 
      end 
    from mytable 
    where id = '345' 
    ), 
    y(wk, cost, grp) as(
    --assign group number 
    select wk, cost, 
      sum(startgroup) over (partition by cost order by wk) 
    from x 
    ), 
    z(wk, cost, grp) as(
    --get the max/min week for each group 
    select case when min(wk) = max(wk) 
       then cast(min(wk) as varchar2(10)) 
       else min(wk) ||'-'||max(wk) 
       end, 
      cost, grp 
    from y 
    group by cost, grp 
    ) 
--aggregate by cost 
select listagg(wk,',') within group(order by grp), 
cost 
from z 
group by cost; 

Demo в sqlfiddle.

+0

Потратьте время, чтобы окунуться в это, но это именно то, что я ищу ... спасибо! – Tom

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