2015-07-29 4 views
1

Мне нужно сделать преобразование из Oracle SQL в PostgreSQL.Преобразование rownum из Oracle в Postgres

select * from table1 inner join table2 on table1.id = table2.table1Id 
    where table1.col1 = 'TEST' 
    and rownum <=5 
    order by table2.col1 

Если удалить and rownum <=5 и поставить в конце limit 5, существует различие между 2 диалектами. В Oracle сначала выбираются 5 элементов, и после этого они сортируются по table2.col1.
В Postgres сначала сортируется весь список, а ПОСЛЕ выбраны первые 5 элементов.

Как получить тот же результат в Postgres, что и в Oracle?

Спасибо!

+0

http://stackoverflow.com/questions/3959692/rownum-in-postgresql – ZaoTaoBao

+0

Поскольку результат в Oracle в основном случайный - нет надежного способа предсказать, какие 5 строк будут выбраны - вероятно, невозможно гарантировать, что запрос возвращает те же результаты в обеих системах. –

ответ

0

В зависимости от версии, которую вы используете, PostgreSQL 8.4 и выше имеют Window functions. Функция окна ROW_NUMBER() способна реализовать функциональность Oracle pseudo column rownum.

select row_number() over() as rownum,* from table1 inner join table2 on table1.id = table2.table1Id where table1.col1 = 'TEST' and rownum <=5 order by table2.col1; 
+1

Хотя функции примечания не допускаются в предложении WHERE, поскольку OP хочет сделать – harmic

+0

@harmic: вы всегда можете поместить select с помощью 'row_number()' в производную таблицу, а затем использовать псевдоним столбца в 'where' пункт. –

+0

Согласно комментарию a_horse_with_no_name, если вы хотите использовать такие оконные функции, вы должны поместить их в производную таблицу (т. Е. Подзапрос в предложении FROM). Недостаточно просто использовать псевдоним в том же запросе. – harmic

1

Чтобы получить поведение вы хотите, вы можете использовать подзапрос, как это:

SELECT * FROM (
    SELECT table1.col1 as t1col1, table2.col1 as t2col1 
    FROM table1 INNER JOIN table2 ON table1.id = table2.table1Id 
    WHERE table1.col1 = 'TEST' 
    LIMIT 5 
) AS sub 
ORDER BY t2col1; 

Я назвал столбцы там, потому что в вашем примере обе таблицы имели col1.

Обратите внимание, что при любом запросе на внутренний запрос выбор из 5 строк, которые вы получите, будет носить чисто случайный характер и может быть изменен.