2016-08-17 31 views
2

我最近開始在Oracle中學習數據庫查詢,但有一點我很難理解關於分組的問題。Oracle SQL Group按列值排列

最好用例子來解釋。假設我的源數據如下所示:

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之一,可能的值是:

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條記錄,所以我認爲我會與您的第一個查詢。 –