2016-08-17 32 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条记录,所以我认为我会与您的第一个查询。 –