2016-08-17 21 views
2

私は最近、Oracleでデータベースクエリを学習し始めましたが、グループ化について多くの問題を理解しています。Oracle SQL Group by Column Valueランク

これは例を用いて最もよく説明されています。ソースデータが次のようになっているとします。

MY_SOURCE 

ID | Fruit 
---------- 
1 | Orange 
1 | Apple 
1 | Orange 
2 | Banana 
2 | Apple 
3 | Apple 
3 | Apple 
3 | Orange 

ある種の果物のランク/優先度が異なるとします。ランク(1 =最も重要、3 =最も重要でない)は:

Fruit Rank: 
1. Banana 
2. Orange 
3. Apple 

IDでデータをグループ化したいとします。これを行うと、集計する必要があるデータソース内の各IDの果物列の複製が作成されます。たとえば、ID 1のために、可能な値のセットがある:

Orange, Apple, Orange 

この時点で、代わりにstats_mode(のようなものとの重複フルーツセットを集約する)、私はフルーツのランクによってグループにデータを希望し、最高ランクの値のみが表示されます。したがって、出力は次のようになります。

ID | Fruit 
---------- 
1 | Orange 
2 | Banana 
3 | Orange 

これをSQLで実行する方法はありますか?私のようなものに見えるクエリ想像してい

:技術的には

SELECT DISTINCT 
    ID, 
    MAGIC_MAX_RANK_FUNCTION(FRUIT, ['Banana','Orange', 'Apple']) 
FROM 
    MY_SOURCE 

を、私たちは、その列の可能なすべての値のため、プログラマによって指定されたランクに応じ重複フルーツのデータをグループ化しています。

ありがとうございます!

答えて

1

代わりのGROUP BY、私はちょうどROW_NUMBER()を使用します。

select s.* 
from (select s.*, 
      row_number() over (partition by id 
           order by (case fruit when 'banana' then 1 when 'orange' then 2 when 'apple' then 3 else 999 end) 
           ) as seqnum 
     from my_source s 
    ) s 
where seqnum = 1; 

もう一つの方法は、union allを使用し、短いリストに最適です:いくつかの状況下

select s.* 
from my_source s 
where s.fruit = 'banana' 
union all 
select s.* 
from my_source s 
where s.fruit = 'orange' and 
     not exists (select 1 from my_source s2 where s2.id = s.id and s2.fruit in ('banana')) 
union all 
select s.* 
from my_source s 
where s.fruit = 'apple' and 
     not exists (select 1 from my_source s2 where s2.id = s.id and s2.fruit in ('banana', 'orange')); 

、この方法はより速いかもしれません以前の方法(およびその逆)。

+0

ゴードン - これは完璧です。どうもありがとうございます!ここの実際のデータは12,000レコード以上ですので、私はあなたの最初のクエリに行くと思います。 –