Oracle - 从表中选择最新的不同记录

时间:2012-03-21 17:57:25

标签: oracle distinct

从理论上讲,这似乎很容易,但我无法理解这个......

这是我的表信息和数据

ID    Heading    Date         Row_Num
 1       Test    12-MAR-12          1
 1      Test2    13-MAR-12          2
 2      Test3    13-MAR-12          3

这是我的查询

select * from 
table1 
where date <= :date 
order by date desc

:date例如14-MAR-12

这显然会产生所有三个结果,但我想从这个查询中获得的是以下数据

ID    Heading    Date         Row_Num
 1      Test2    13-MAR-12          2
 2      Test3    13-MAR-12          3

所以我添加了distinct,但这不能按预期工作,因为我必须按每列分组,并且通过这样做它仍会产生3个结果。

关于如何完成我之后的结果的任何想法?

3 个答案:

答案 0 :(得分:4)

您需要使用分析功能。 row_number函数应该可以解决问题。

select *
from
(
    select 
        id,
        heading,
        date,
        row_number() over ( partition by id order by heading desc nulls last ) r
    from table1
)
where r = 1

分析函数可用于对结果集中的行执行分析和分组。在上面的示例中,内部选择查询table1照常。 row_number()函数将每行与其他返回的行(使用分区语句中提供的聚合)进行比较以生成数字。在这种情况下,我们按ID分组,按标题降序排序。 outer-select有一个where子句,用于过滤掉row_number为1的行。只运行内部选择,看看整个事情是如何工作的。

答案 1 :(得分:3)

如果您只想为每个DT添加最新ID的行,您会想要类似

的内容
SELECT id,
       heading,
       dt
  FROM (SELECT id,
               heading,
               dt,
               ROW_NUMBER() OVER (PARTITION BY id
                                      ORDER BY dt desc) rnk
          FROM table1)
 WHERE rnk = 1

如果可以建立联系(两行具有相同的IDDT,您可能需要在分析函数中向ORDER BY添加其他内容,以确定性地打破平局,而不是让Oracle任意破坏它。

答案 2 :(得分:1)

我可能误解了你想要实现的目标,但我认为你可以通过group by和子查询来实现,如下所示:

SELECT * 
FROM table1 
WHERE ID||date IN 
  (SELECT ID||MAX(date)
  FROM table1 
  WHERE date <= to_date('14-mar-12', 'DD-mon-YY') 
  GROUP BY ID
  );

只要没有多个具有相同ID和相同日期的行,这将为每个ID和日期提供一行。