Oracle rownum на "родительском" столе

Мы используем 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 строк. Но мы хотим вернуть первые 500 строк из t1 - а потом все t2 строки, которые идут вместе с этим. Каков наилучший способ сделать это?

Мы могли бы удалить rownum Использование SQL и в Java только что прочитал первые 500 уникальных t1.key значения из результирующего набора (всего будет более 500 строк в результирующем наборе). Но не ясно, будет ли это значительно медленнее.

2 ответа

Я думаю, что вы можете сделать это с помощью 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 значение будет сгруппировано, поэтому неясно, как ваша логика "первых 500 строк" ​​должна работать на основе t1.key,

Не существует понятия "первые 500 строк таблицы", поскольку таблицы представляют неупорядоченные множества. Но, если вы имеете в виду под 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) должно сработать. Неясно, будет ли это работать с неизвестными условиями.

Другие вопросы по тегам