2010-12-15 65 views
1

我有一个非常大的查询,其中对我造成一些麻烦,因为一个连接可以返回多行。我只想要这个结果集中的最新行(由日期字段标识),但我似乎无法将正确的查询放在一起以使其工作。Oracle查询需要返回结果中的最高日期

查询我需要MAX日期从是:

SELECT custid,reason,date FROM OPT opt WHERE opt.custid = 167043; 

德客户ID通过加入才真正发现,但为了简单起见,我把它添加到这里的where子句。此查询产生以下结果:

custid grunn  date 
167043 "Test 1" 19.10.2005 12:33:18 
167043 "Test 2" 28.11.2005 16:23:35 
167043 "Test 3" 14.06.2010 15:43:16 

如何从此结果集中只检索一条记录?那个纪录是最高的日期?最终,我把这个变成了一个很大的查询,它可以完成很多连接,所以我希望我可以将这个例子用于更大的查询。

回答

1

你可以这样做:

SELECT * FROM 
(SELECT custid,reason,date FROM OPT opt WHERE opt.custid = 167043 
    ORDER BY date DESC 
) 
WHERE ROWNUM = 1; 
1

您可以使用分析函数解决它。尝试是这样的:

select custid 
     ,reason 
     ,date 
    from (select custid 
       ,reason 
       ,date 
       ,row_number() over(partition by cust_id order by date desc) as rn 
     from opt) 
where rn = 1; 

这是它的工作原理:该结果集分为CUST_ID(partition by)组。在每个组中,行将按日期列降序排列(order by)。组内的每个行将从1被分配一个序列号(row_number)至N. 这种方式与日期最高值的行会被分配1,第二最新2,第三最新3等。

最后,我只是选择nr = 1的行,它基本上过滤了其他行。

0

或者使用其聚合形式LAST功能的另一种方式。

with my_source_data as (
    select 167043 as custid, 'Test 1' as reason, date '2010-10-01' as the_date from dual union all 
    select 167043 as custid, 'Test 2' as reason, date '2010-10-02' as the_date from dual union all 
    select 167043 as custid, 'Test 3' as reason, date '2010-10-03' as the_date from dual union all 
    select 167044 as custid, 'Test 1' as reason, date '2010-10-01' as the_date from dual 
) 
    select 
     custid, 
     max(reason) keep (dense_rank last order by the_date) as reason, 
     max(the_date) 
    from my_source_data 
    group by custid 

我觉得这非常有用,因为它将查找最后一行和值全部合并为一个过程。在分组和order by的组合不确定的情况下,使用MAX(或另一个聚合函数,例如MIN)。

该功能基本上将基于分组的列的内容,按给定的顺序排序,然后取最后一个值。

0

,而不是使用ROW_NUMBER(),我认为这是更好地选择你真的想选择(例如最后日期)什么

SELECT custid 
,  reason 
,  date 
from 
(
    SELECT custid 
    ,  reason 
    ,  date 
    ,  max(opt.date) over (partition by opt.custid order by opt.date) last_date 
    FROM OPT opt 
    WHERE opt.custid = 167043; 
) 
where date = last_date 
+0

......虽然你运行返回多行的风险,如果日期是不是唯一的 – 2010-12-15 12:55:46

+0

这是一个很好的点... – winkbrace 2010-12-16 15:14:04

0

与ROW_NUMBER两种解决方案,并保持良好。在检索大量列时,我会倾向于更喜欢ROW_NUMBER,并且保留一两列的KEEP,否则您将不得不处理重复项,并且语句会变得很难理解。

对于少数列然而,要性能应该更好

+1

没你几年前在你的博客上写了一些关于使用“保持”多列的东西(如本例中)?添加到你的答案,我会upvote它。 – Ronnis 2010-12-15 15:57:05