Миграция Oracle спецификаций c sql на postgresql - PullRequest
0 голосов
/ 10 июля 2020

Oracle:

select RANK () OVER (PARTITION BY EQUIP_UNIT_INIT_CODE ORDER BY EQUIP_UNIT_INIT_CODE, ROWNUM)  from CAR_SEARCH_GTT;

Postgres:?

Проблема: в postgresql нет Rownum, если мы используем row_number() over () вместо ROWNUM, будет выбрано исключение PSQLException.

ERROR: window functions are not allowed in window definitions

Вопрос: Как преобразовать запрос выше в PostgreSQL?

Ответы [ 2 ]

2 голосов
/ 10 июля 2020

Использование недетерминированных c ROWNUM имеет смысл, если вы не хотите, чтобы RANK() числа повторялись в случае ничьей.

Тем не менее, как сказал @a_horse_with_no_name, это не имеет смысла в ORDER BY тот же столбец, что и вы PARTITION BY.

Попробуйте это:

with numbered as (
  select *, row_number() over () as rnum
    from CAR_SEARCH_GTT
)
select RANK () OVER (PARTITION BY EQUIP_UNIT_INIT_CODE 
                         ORDER BY EQUIP_UNIT_INIT_CODE, rnum)  
  from CAR_SEARCH_GTT;

Если ПК на CAR_SEARCH_GTT как id, то вы можете сделать что-то вроде этого:

select RANK () OVER (PARTITION BY EQUIP_UNIT_INIT_CODE 
                         ORDER BY EQUIP_UNIT_INIT_CODE, id)  
  from CAR_SEARCH_GTT;
0 голосов
/ 10 июля 2020

SQL таблица представляет неупорядоченные наборы. Без явной сортировки строки расположены в произвольном порядке. Если ключи сортировки не уникальны, то связи располагаются в произвольном порядке.

Тогда вам не нужно повторять клавишу PARTITION BY в ORDER BY для оконных функций. Вы можете написать то, что хотите, в Oracle как:

select RANK() OVER (PARTITION BY EQUIP_UNIT_INIT_CODE ORDER BY ROWNUM) 
from CAR_SEARCH_GTT;

Несмотря на rownum, порядок будет произвольный . Oracle не дает никаких гарантий относительно порядка в каждой группе.

Единственный эффект rownum состоит в том, чтобы иметь разные значения в каждой строке. Следовательно, нет никаких связей. Это более четко выражено с помощью ROW_NUMBER():

select ROW_NUMBER() OVER (PARTITION BY EQUIP_UNIT_INIT_CODE ORDER BY ROWNUM) 
from CAR_SEARCH_GTT;

Oracle требует предложения ORDER BY, поэтому все может go там.

В Postgres вы можете сделайте то же самое, удалив ORDER BY - Postgres расширяет синтаксис ROW_NUMBER. Таким образом, эквивалент:

select ROW_NUMBER() OVER (PARTITION BY EQUIP_UNIT_INIT_CODE) 
from CAR_SEARCH_GTT;

В обоих случаях у вас может быть соответствующий ключ для упорядочивания - возможно, столбец идентификаторов или дата создания.

...