5

t次のように入力されたテーブルがあるとします。

x y z 
- - - 
A 1 A 
A 4 A 
A 6 B 
A 7 A 
B 1 A 
B 2 A 

基本的に、列 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

つまり、行が x、y、および z で順序付けられている場合、 x および z の連続するグループごとに最小および最大の y を選択します。

このクエリは必要なものではないことに注意してください。

select x, z, min(y), max(y)
from t
group by x, z

これにより、次の望ましくない結果が生じるため:

x z min(y) max(y)
- - ------ ------
A A 1      7
A B 6      6
B A 1      2

質問は、SQL で必要なものを表現する方法はありますか?

(ソリューションが SQL ダイアレクトに依存する場合: Oracle ソリューションが優先されます。)

4

3 に答える 3

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

SQLFIDDLE でテストします。

于 2013-09-26T12:32:55.037 に答える
1

お使いのバージョンがWITHおよびROW_NUMBER() OVERをサポートしている場合、Oracle のバージョンについて言及しませんでした

WITH C as
(
select t.*,
       ROW_NUMBER() OVER (order by x,y,z ) as rn
from t
), C2 as 

(
select t1.*,
( 
  select count(*) from c where Rn<=t1.Rn 
                               and (z<>t1.z or x<>t1.x) 
) as Grp
from c t1
) 

select x,z,min(y),max(y) from c2 
group by x,z,grp
order by min(rn)

SQLFiddle デモ

于 2013-09-26T12:27:02.360 に答える