查询最新记录的快捷方式?

fil*_*ppo 5 sql oracle performance

我有一张桌子:

USER |  PLAN |  START_DATE  |   END_DATE
1    |  A    |  20110101    |   NULL
1    |  B    |  20100101    |   20101231
2    |  A    |  20100101    |   20100505
Run Code Online (Sandbox Code Playgroud)

以if END_DATEnull方式表示该用户当前有该计划处于活动状态.

我想要查询的是:(a)他当前的计划,或者(b)他进入的最新计划.我只需要为每个给定用户返回一行.

现在,我设法在使用联合和子查询时这样做,但是发生这种情况很严重,而且效率不高.你们中的任何人都有更快的方法来查询吗?

谢谢,

[编辑]这里的大多数答案都返回一个值.那是我的坏事.我的意思是每个用户返回一个值,但一次返回所有用户.我已经调整了我能做的答案(并纠正了问题),但只是明确了以备将来参考.

Mik*_*ers 3

如果没有有关数据和表格的进一步信息,这个问题有点难以回答。当您在评论中说您拥有所需的所有索引时,这些索引是什么?

另外,时间段是否相邻且不重叠?您能否获取最近 START_DATE 的时间段?

查看 END_DATE 的问题是普通的 B 树索引不会索引 NULL。因此,这种形式的谓词where end_date is nulll不太可能使用索引。您可以对列使用位图索引,因为这些类型的索引会对空值进行索引,但这可能并不理想,因为位图索引还有一些其他缺点。

由于上述原因,我可能会使用类似于以下查询的查询:

select user, plan, start_date, end_date
from (
  select 
    user, 
    plan, 
    start_date, 
    end_date, 
    row_number() over (partition by user order start_date desc) as row_num_1,
    row_number() over (partition by user order end_date desc nulls first) as row_num_2
  from user_table
  where user = :userid
)
where row_num_1 = 1
Run Code Online (Sandbox Code Playgroud)

根据具体要求,您可以在此处使用 或row_num_1列。row_num_2

或者

select user, plan, start_date, end_date
from (
  select 
    user, 
    plan, 
    start_date, 
    end_date, 
  from user_table
  where user = :userid
  order by start_date desc
)
where rownum = 1
Run Code Online (Sandbox Code Playgroud)

无论您是尝试恢复所有用户还是仅恢复一个用户,第一个查询都应该有效。第二个查询仅适用于一个用户。

如果您可以使用架构的更多详细信息(索引、开始/结束日期的含义)来补充问题,您可能会得到更好的答案。