首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查找最大值和相关字段

查找最大值和相关字段
EN

Stack Overflow用户
提问于 2014-05-14 22:55:37
回答 2查看 62关注 0票数 0

这是我的(简化的)问题,我想这是很常见的:

create table sample (client, recordDate, amount)

我想找出最新的记录,为每个客户,与recordDate和金额。

我编写了下面的代码,它可以工作,但我想知道是否有更好的模式或Oracle调整来提高这种选择的效率。(我不被允许修改数据库的结构,所以索引等对我来说是遥不可及的,也超出了这个问题的范围)。

代码语言:javascript
复制
select client, recordDate, Amount 
from sample s
inner join (select client, max(recordDate) lastDate
            from sample 
            group by client) t on s.id = t.id and s.recordDate = t.lastDate

该表有50万条记录,select需要2-4秒,这是可以接受的,但我很好奇是否可以改进。

谢谢

EN

回答 2

Stack Overflow用户

发布于 2014-05-14 22:59:14

在大多数情况下,窗口聚合函数的性能可能会更好(至少它更容易编写):

代码语言:javascript
复制
select client, recordDate, Amount 
from 
  (
   select client, recordDate, Amount,
      rank() over (partition by client order by recordDate desc) as rn 
   from sample s
  ) dt
where rn = 1
票数 2
EN

Stack Overflow用户

发布于 2014-05-14 23:14:26

查询的另一个结构是not exists。在某些情况下,这可能会执行得更快:

代码语言:javascript
复制
select client, recordDate, Amount 
from sample s
where not exists (select 1
                  from sample s2
                  where s2.client = s.client and
                        s2.recordDate > s.recordDate
                 );

这将很好地利用sample(client, recordDate)上的索引(如果有)。

另一件可以尝试的事情是keep

代码语言:javascript
复制
select client, max(recordDate),
       max(Amount) keep (dense_rank first order by recordDate desc)
from sample s
group by client;

此版本假设每个客户端只有一个最大记录日期(您的原始查询不做此假设)。

这些查询(加上dnoeth的查询)应该都有不同的查询计划,您可能会幸运地找到其中一个。不过,最好的解决方案是拥有适当的索引。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23658237

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档