2017-04-16 44 views
2

我有一組簡單的表(ID)(GRP_ID)。找到每組其他行的最大值

create table tst as 
select 1 grp_id, 1 id from dual union all 
select 1 grp_id, 1 id from dual union all 
select 1 grp_id, 2 id from dual union all 
select 2 grp_id, 1 id from dual union all 
select 2 grp_id, 2 id from dual union all 
select 2 grp_id, 2 id from dual union all 
select 3 grp_id, 3 id from dual; 

它是簡單的找到每使用分析功能組的最大值。

select grp_id, id, 
max(id) over (partition by grp_id) max_grp 
from tst 
order by 1,2; 

    GRP_ID   ID MAX_GRP 
---------- ---------- ---------- 
     1   1   2 
     1   1   2 
     1   2   2 
     2   1   2 
     2   2   2 
     2   2   2 
     3   3   3 

但目標是找到排除當前行的值的最大值。

這是預期的結果(柱MAX_OTHER_ID):

GRP_ID   ID MAX_GRP MAX_OTHER_ID 
---------- ---------- ---------- ------------ 
     1   1   2   2 
     1   1   2   2 
     1   2   2   1 
     2   1   2   2 
     2   2   2   2 
     2   2   2   2 
     3   3   3    

注意,在GRP_ID = 2上的MAX值存在平局,所以MAX_OTHER_ID保持相同。

我確實管理了這個兩步驟的解決方案,但我想知道是否有更直接簡單的解決方案。

with max1 as (
select grp_id, id, 
row_number() over (partition by grp_id order by id desc) rn 
from tst 
) 
select GRP_ID, ID, 
case when rn = 1 /* MAX row per group */ then 
    max(decode(rn,1,to_number(null),id)) over (partition by grp_id) 
else 
    max(id) over (partition by grp_id) 
end as max_other_id 
from max1 
order by 1,2 

;

回答

4

祝窗口功能支持多個規格品種齊全是這樣的:

max(id) over (
     partition by grp_id 
     order by id 
     range between unbounded preceding and 1 preceding 
     or range between 1 following and unbounded following 
     ) 

但不幸的是他們不這樣做。

作爲一種解決方法,您可以避免子查詢和CTE在不同範圍上使用該函數兩次,並在該範圍上調用​​3210。

select grp_id, 
    id, 
    coalesce(
      max(id) over (
       partition by grp_id 
       order by id 
       range between 1 following and unbounded following 
       ) 
      , max(id) over (
       partition by grp_id 
       order by id 
       range between unbounded preceding and 1 preceding 
       ) 
      ) max_grp 
from tst 
order by 1, 
    2 

合併開箱,因爲排序子句作爲窗口函數調用的結果將是無論是在給定的窗口的最大或空值。

演示 - http://rextester.com/SDXVF13962

+1

完美的解決方案。我被困了一段時間,並且正準備告訴OP它不能在單個查詢中完成。這就是你的美麗,你總是會學到新的東西。 – Utsav

+0

積極的'​​ID'的好方案。 –

+0

@MarmiteBomber - 我認爲,是的。 – GurV

1
SELECT GRP_ID,ID, (SELECT Max(ID) FROM TEST A WHERE A.ROWID<>B.ROWID AND A.GRP_ID=B.GRP_ID) maX_ID FROM TEST B; 

得到了與合作相關的查詢期望的結果!希望這可以幫助 。

相關問題