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