4

私は苦労していますGROUP BY--再び。group by処理できる基本事項は次のとおりです。グループ化を破棄せずに、 で名前を付けた別の列にアクセスするにはどうすればよいですか? group byあくまでも私個人の考えですので、他にもっとうまくいくものがあるかもしれません。ただし、Oracleでは機能する必要があります。

これが私の例です:

create table xxgroups (
  groupid int not null primary key,
  groupname varchar2(10)
);
insert into xxgroups values(100, 'Group 100');
insert into xxgroups values(200, 'Group 200');

drop table xxdata;
create table xxdata (
  num1 int,
  num2 int,
  state_a int,
  state_b int,
  groupid int,
    foreign key (groupid) references xxgroups(groupid)
);
-- "ranks" are 90, 40, null, 70:
insert into xxdata values(10, 10, 1, 4, 100);
insert into xxdata values(10, 10, 0, 4, 200);
insert into xxdata values(11, 11, 0, 3, 100);
insert into xxdata values(20, 22, 5, 7, 200);

タスクは、それぞれの結果行を作成し、とから計算された「ランク」が最も高いdistinct (num1, num2)ものを出力することです。groupnamestate_astate_b

最初の 2 行の s は同じであるため、 「グループ 200」numという上位のランキングのみを選択する必要があることに注意してください。groupname

私は基本的なことでかなり遠くまで来たgroup byと思います。

SELECT xd.num1||xd.num2 nummer, max(ranking.goodness)
FROM xxdata xd
    , xxgroups xg
    ,( select state_a, state_b, r as goodness
       from dual
       model return updated rows
       dimension by (0 state_a, 0 state_b) measures (0 r)
       rules (r[1,4]=90, r[3,7]=80,r[5,7]=70, r[4,7]=60, r[0,7]=50, r[0,4]=40)
       order by goodness desc
      ) ranking
WHERE xd.groupid=xg.groupid
  and ranking.state_a (+) = xd.state_a
  and ranking.state_b (+) = xd.state_b
GROUP BY xd.num1||xd.num2
ORDER BY nummer
;

結果は、必要なものの 90% です。

nummer   ranking
----------------
1010     90
1111      
2022     70

100%完璧だろう

nummer   groupname
-------------------
1010     Group 100
1111     Group 100
2022     Group 200
  • トリッキーな部分は、結果が欲しいというgroupnameことです。そして、それを に含めることはできませんselect。なぜなら、それを にも入れなけれgroup byばならないからです-- これは望ましくありません (そうすれば、すべてのグループから最高のランキング エントリを選択しません)。
  • 私の解決策では、modelテーブルを使用して「ランク」を計算します。私が確信している他の解決策があります。ポイントは、2 度やりたくない重要な計算であるということです。
  • 他の例から、2 番目のクエリを使用して元の行に戻ってgroupname.
  • group byLIMIT 1/に置き換えて、ORDER BY goodnessこの計算選択をフィルタリング サブ選択として使用することをお勧めします。しかし、a)LIMITオラクルには存在しrownum<=1ません。副選択で a が行うとは思えません。b) いずれにせよ、頭を悩ませることはできません。多分方法はありますか?
4

2 に答える 2

2

うわー、以前に検索しましたが、今ではこの答えを見つけました。これを質問に採用できます。ここでのオラクルの解決策はoverpartition byと:order byrow_number()

select *
from ( select data.*, row_number()
         over (partition by nummer order by goodness desc) as seqnum
from (
SELECT xd.num1, xd.num2 nummer, xg.groupname, ranking.goodness
FROM xxdata xd
    , xxgroups xg
    ,( select state_a, state_b, r as goodness
       from dual
       model return updated rows
       dimension by (0 state_a, 0 state_b) measures (0 r)
       rules (r[1,4]=90, r[3,7]=80,r[5,7]=70, r[4,7]=60, r[0,7]=50, r[0,4]=40)
      ) ranking
WHERE xd.groupid=xg.groupid
  and ranking.state_a (+) = xd.state_a
  and ranking.state_b (+) = xd.state_b
ORDER BY nummer
) data )
where seqnum = 1
;

結果は

    10         10 Group 100          90          1
    11         11 Group 100                      1
    20         22 Group 200          70          1

美しいです。

今、私は正確に何をするのかを理解しようとしなければoverなりselectません....

于 2012-11-14T11:39:10.983 に答える