SQL Local Minima和Maxima

时间:2014-11-13 23:14:42

标签: sql oracle gaps-and-islands

我有这些数据:

row_id  type    value
1       a       1
2       a       2
3       a       3
4       a       5        --note that type a, value 4 is missing
5       a       6
6       a       7
7       b       1
8       b       2
9       b       3
10      b       4
11      b       5        --note that type b is missing no values from 1 to 5
12      c       1
13      c       3        --note that type c, value 2 is missing

我想找到每个连续"运行"的最小值和最大值。在每个type内。也就是说,我想返回

row_id  type    group_num   min_value   max_value
1       a       1           1           3
2       a       2           5           7
3       b       1           1           5
4       c       1           1           1
5       c       2           3           3

我是一位经验丰富的SQL用户,但我从未解决过这个问题。显然,我知道如何使用typeGROUPMIN获取每个MAX的总体最小值和最大值,但我真的感到茫然这些局部最小值和最大值。我还没有找到任何可以回答我问题的其他问题。

我正在使用PLSQL Developer和Oracle 11g。谢谢!

2 个答案:

答案 0 :(得分:3)

这是一个缺口和岛屿问题。您可以使用an analytic function effect/trick查找每种类型的连续值链:

select type,
  min(value) as min_value,
  max(value) as max_value
from (
  select type, value,
    dense_rank() over (partition by type order by value)
      - dense_rank() over (partition by null order by value) as chain
  from your_table
)
group by type, chain
order by type, min(value);

内部查询使用类型中的值和整个结果集中的值的排名之间的差异来创建“链”数。外部查询仅将其用于分组。

SQL Fiddle包括内部查询的结果。

答案 1 :(得分:0)

这是达到所需结果的一种方法:

with step_1 as (
    select w.type,
           w.value,
           w.value - row_number() over (partition by w.type order by w.row_id) as grp
    from   window_test w
), step_2 as (
    select x.type,
           x.value,
           dense_rank() over (partition by x.type order by x.grp) as grp
    from   step_1 x
)
select rank() over (order by y.type, y.grp) as row_id,
       y.type, 
       y.grp as group_num,
       min(y.value) as min_val,
       max(y.value) as max_val
from   step_2 y
group by y.type, y.grp
order by 1;