Oracle查询需要从结果返回最高日期

时间:2010-12-15 09:26:53

标签: sql oracle

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

我需要MAX date的查询是:

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

真的通过连接找到了custid,但为了简单起见,我已将其添加到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

如何从此结果集中仅检索一条记录?那个记录是日期最长的记录吗?最终我把它放到一个大查询中,这个查询有很多连接,所以希望我可以将这个例子用于我更大的查询。

5 个答案:

答案 0 :(得分: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到N的序列号(row_number)。 这样,具有最高日期值的行将被分配1,第二个最新的2,第三个最新的3等。

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

答案 1 :(得分:1)

你可以这样做:

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

答案 2 :(得分: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

我发现这非常有用,因为它将查找最后一行和值all的过程滚动到一个。如果分组和顺序的组合不是确定性的,则使用MAX(或其他聚合函数,例如MIN)。

此函数基本上会根据分组获取列的内容,按给定的顺序对其进行排序,然后取最后一个值。

答案 3 :(得分: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

答案 4 :(得分:0)

使用ROW_NUMBER和KEEP的两个解决方案都很好。我倾向于在检索大量列时更喜欢ROW_NUMBER,并保留一个或两个列的KEEP,否则你将不得不处理重复项,并且该语句将变得非常难以理解。

但是对于少量列,KEEP应该表现更好