0

Oracle:

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

Postgres: ?

Issue: there is no Rownum in postgresql, if we use row_number() over () instead of ROWNUM, the PSQLException would be thrown.

ERROR: window functions are not allowed in window definitions

Question: How to convert the query above to PostgreSQL?

11
  • What is the order by on the overall select? The reason I ask is because Oracle generates rownum based on the order. Commented Jul 10, 2020 at 9:13
  • @a_horse_with_no_name thank you for responding me, I've updated the query. sorry that's my fault. Commented Jul 10, 2020 at 9:15
  • @MikeOrganek yes, but Postgresql didn't support ROWNUM Commented Jul 10, 2020 at 9:16
  • Using the same column in partition by and order by still makes no sense. Commented Jul 10, 2020 at 9:16
  • I've deleted my answer because I agree with @a_horse_with_no_name. The query does not make a lot of sense. It seems your partitioning is done in an nondeterministic way. And will most likely behave differently when ported. Commented Jul 10, 2020 at 9:20

2 Answers 2

2

Using a non-deterministic ROWNUM makes sense if you do not want RANK() numbers repeated in the case of ties.

That said, as @a_horse_with_no_name said, it make no sense whatsoever to ORDER BY the same column that you PARTITION BY.

Please try this:

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;

If there is a PK on CAR_SEARCH_GTT as id, then you can do something like this:

select RANK () OVER (PARTITION BY EQUIP_UNIT_INIT_CODE 
                         ORDER BY EQUIP_UNIT_INIT_CODE, id)  
  from CAR_SEARCH_GTT;
Sign up to request clarification or add additional context in comments.

Comments

0

SQL table represent unordered sets. Without an explicit sort, the rows are in arbitrary order. If the sort keys are not unique, then ties are in an arbitrary order.

Then, you don't need to repeat the PARTITION BY key in the ORDER BY for window functions. You could write what you want in Oracle as:

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

Despite the rownum, the ordering is arbitrary. Oracle makes no guarantee on the ordering within each group.

The one effect of rownum is to have a different value on each row. Hence, there are no ties. This is more clearly expressed using ROW_NUMBER():

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

Oracle requires an ORDER BY clause, so anything can go there.

In Postgres, you can do the same thing by removing the ORDER BY -- Postgres extends the syntax of ROW_NUMBER. So the equivalent is:

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

In both cases, you might have an appropriate key for ordering -- perhaps an identity column or creation date.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.