在排序之前将一些行“分组”(Oracle)

时间:2013-07-25 14:53:24

标签: sql oracle plsql oracle11g

我正在使用Oracle Database 11g。 我有一个查询,从表中选择ID和日期等。基本上,我想要做的是将具有相同ID的行保持在一起,然后按“组”中最近的日期对行的“组”进行排序。

所以如果我原来的结果是这样的话:

ID   Date
3    11/26/11
1    1/5/12
2    6/3/13
2    10/15/13
1    7/5/13

我希望的输出是:

ID   Date
3    11/26/11     <-- (Using this date for "group" ID = 3)
1    1/5/12
1    7/5/13       <-- (Using this date for "group" ID = 1)
2    6/3/13
2    10/15/13     <-- (Using this date for "group" ID = 2)

有没有办法做到这一点?

3 个答案:

答案 0 :(得分:2)

获得此功能的一种方法是使用分析函数;我没有那个方便的例子。

这是获取指定结果的另一种方法,不使用分析函数(这是首先按每个ID的most_recent_date排序,然后按ID排序,然后按日期排序):

SELECT t.ID
     , t.Date
  FROM mytable t
  JOIN ( SELECT s.ID
              , MAX(s.Date) AS most_recent_date
           FROM mytable s
          WHERE s.Date IS NOT NULL
          GROUP BY s.ID
       ) r
    ON r.ID = t.ID
 ORDER
    BY r.most_recent_date
     , t.ID
     , t.Date

这里的“技巧”是为每个ID返回“most_recent_date”,然后将其连接到每一行。结果可以先按顺序排序,然后按其他顺序排序。

(我也认为有一种方法可以使用Analytic函数获得相同的排序,但我没有这方面的例子。)

答案 1 :(得分:1)

您可以将MAX ... KEEP功能与聚合一起使用来创建排序键:

with 
  sample_data as
   (select 3 id, to_date('11/26/11','MM/DD/RR') date_col from dual union all
    select 1,  to_date('1/5/12','MM/DD/RR') date_col from dual union all
    select 2, to_date('6/3/13','MM/DD/RR') date_col from dual union all
    select 2, to_date('10/15/13','MM/DD/RR') date_col from dual union all
    select 1, to_date('7/5/13','MM/DD/RR') date_col from dual)
select 
  id,
  date_col,
  -- For illustration purposes, does not need to be selected:
  max(date_col) keep (dense_rank last order by date_col) over (partition by id) sort_key
from sample_data
order by max(date_col) keep (dense_rank last order by date_col) over (partition by id);

答案 2 :(得分:1)

以下是使用分析函数的查询:

select 
  id
, date_
, max(date_) over (partition by id) as max_date
  from table_name
  order by max_date, id 
;