我有一个这样的表:
USER | PLAN | START_DATE | END_DATE
1 | A | 20110101 | NULL
1 | B | 20100101 | 20101231
2 | A | 20100101 | 20100505
在某种程度上,如果
END_DATE
是 null
, 表示该用户当前拥有该计划。我要查询的是:
(a) 他当前的计划,或 (b) 他最近参与的计划。我只需要为每个给定用户返回一行。
现在,我设法在使用联合和子查询时做到了这一点,但碰巧该表很大,而且效率不够高。
你们有没有更快的方法来查询?
谢谢,
[编辑]
这里的大多数答案都返回一个值。那是我的坏处。我的意思是为每个用户返回一个值,但一次返回所有用户。我已经调整了我可以的答案(并更正了问题),但只是为了将来引用而明确。
最佳答案
如果没有关于数据和表格的更多信息,这个问题有点难以回答。当您在评论中说您拥有所需的所有索引时,这些索引是什么?
此外,时间段是否相邻且不重叠?您能获取最新 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
您可能可以使用
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
无论您是尝试让所有用户回来还是只让一个用户回来,第一个查询都应该有效。第二个查询仅适用于一个用户。
如果您可以使用模式的更多详细信息(索引、开始/结束日期的含义)来扩充问题,您可能会得到更好的答案。
关于sql - 查询最新记录的快速方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6095928/