如何在SQL中聚合有序的行子集?

Rub*_*ick 5 sql oracle

假设我有一个t像这样填充的表:

x y z 
- - - 
A 1 A 
A 4 A 
A 6 B 
A 7 A 
B 1 A 
B 2 A 
Run Code Online (Sandbox Code Playgroud)

基本上,列x和z是随机字母和y随机数.

我想按如下方式聚合行:

x z min(y) max(y)
- - ------ ------
A A 1      4
A B 6      6
A A 7      7
B A 1      2
Run Code Online (Sandbox Code Playgroud)

换句话说:假设行按x,y和z排序,请为每个连续的x和z组选择最小和最大y .

请注意,此查询不是我需要的:

select x, z, min(y), max(y)
from t
group by x, z
Run Code Online (Sandbox Code Playgroud)

因为这会导致以下不需要的结果:

x z min(y) max(y)
- - ------ ------
A A 1      7
A B 6      6
B A 1      2
Run Code Online (Sandbox Code Playgroud)

所以问题是:有没有办法在SQL中表达我想要的东西?

(如果解决方案依赖于SQL方言:首选Oracle解决方案.)

Flo*_*ita 2

这是一个解决方案,但我没有时间逐步解释:

select x, z, min(y), max(y)
from (
  select b.* , sum(switch) over (order by rn) as grp_new 
  from(
    select a.* , 
           case when grp = (lag(grp) over (order by rn))
           then 0 
           else 1 end as switch
    from 
        (select x,y,z, 
                dense_rank() over (order by x, z) as grp,
                row_number() over (order by x, y, z) rn
         from t
    )a
  )b
)c
group by x, z, grp_new
order by grp_new
Run Code Online (Sandbox Code Playgroud)

SQLFIDDLE 来测试它。