我们使用Oracle rownum
来查询两个具有一对多关系的表t1->t2
:
select * from
(
select t1.key, t1.a, t2.b
from t1, t2
where t1.key=t2.key and <filter conditions>
order by t1.a, t2.b
)
where rownum <= 500
这很好,因为它返回前500行。但我们想要的是从t1
返回前500行 - 然后返回与之一致的所有t2
行。最好的方法是什么?
我们可以删除rownum
sql用法,在Java中只读取结果集中的前500个唯一t1.key
值(结果集中总行数超过500)。但目前尚不清楚这是否会明显变慢。
答案 0 :(得分:4)
我认为您可以使用dense_rank()
分析函数来完成此任务:
select * from
(
select t1.key, t1.a, t2.b,
dense_rank() over (order by t1.a, t1.key) as rnk
from t1, t2
where t1.key=t2.key
and <filter conditions>
)
where rnk <= 500
order by a, b
对于它的价值,如果你养成使用ANSI连接语法的习惯会更好。
修改强>
如果t1.a
保证在t1
中具有唯一值,则上述情况应该可以正常工作。如果没有,那么您可能会发现我的查询与原始查询的order by
逻辑完全匹配。但我不知道我能做些什么。
问题在于,因为您按t1.a, t2.b
订购,然后在原始查询中,无法保证具有相同t1.key
值的所有结果将被组合在一起,这使得它不清楚你的&#34;前500行&#34;逻辑应该基于t1.key
。
答案 1 :(得分:0)
没有&#34;表的前500行&#34;的概念,因为表代表无序集。但是,如果你的意思是t1.a
,那么这可能会更快:
select . . .
from (select t.*
from (select t1.*,
from t1
where exists (select 1 from t2 where t2.key = t1.key and <conditions>)
order by t1.a
) t1
where rownum <= 500
) join
t2
on t1.key = t2.key and <filter conditions>
order by t1.a, t2.b;
这是否更快取决于子查询是否可以使用索引。如果没有过滤条件,则t1(a, key)
上的索引将起作用。目前还不清楚这是否适用于未知条件。