简体   繁体   中英

Oracle rownum on “parent” table

We use Oracle rownum to query two tables t1->t2 which have a one to many relationship:

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

This works fine in that it returns the first 500 rows. But what we want is to return the first 500 rows from t1 - and then all the t2 rows that go along with that. What is the best way to do that?

We could remove the rownum sql usage and in Java just read the first 500 unique t1.key values from the resultset (which will be more than 500 total rows in the resultset). But it's not clear if that would be significantly slower.

I think you can accomplish this by using the dense_rank() analytic function:

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

For what it's worth, it would be preferable if you get in the habit of using the ANSI join syntax.

EDIT

The above should work fine if t1.a is guaranteed to have unique values in t1 . If not, then you may find that my query doesn't quite match the order by logic of your original query. But I don't know if there is anything I can do.

The problem is that because you order by t1.a, t2.b , then, in your original query, there is no guarantee that all the results with the same t1.key value will be grouped together, which makes it unclear how your "first 500 rows" logic is supposed to work based on t1.key .

There is no concept of "first 500 rows of a table", because tables represent unordered sets. But, if you mean by t1.a , then this might be faster:

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;

Whether this is faster depends on whether the subquery can make use of indexes. Without the filter condition, then an index on t1(a, key) would work. It is unclear if that would work with the unknown conditions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM