I am trying to generate a query with an ordered ranking of duplicates. For example if I have the following table
id | col1 | col2 | col3
---+------+------+------
1 | 3 | a | x
2 | 2 | a | y
3 | 1 | b | y
4 | 2 | c | z
5 | 3 | a | x
6 | 3 | a | x
7 | 2 | a | y
My desired output would be:
id | col1 | col2 | col3 | rank
---+------+------+------+-----
1 | 3 | a | x | 1
2 | 2 | a | y | 2
3 | 1 | b | y | 3
4 | 2 | c | z | 4
5 | 3 | a | x | 1
6 | 3 | a | x | 1
7 | 2 | a | y | 2
Where the all rows that are equal across the columns are similarly ranked and the ranking starts from 1 in the original order.
I have tried
SELECT
id
, DENSE_RANK() OVER (ORDER BY col1, col2, col2) AS rank
FROM
test_table;
but what I get is
id | col1 | col2 | col3 | rank
---+------+------+------+-----
1 | 3 | a | x | 4
2 | 2 | a | y | 2
3 | 1 | b | y | 1
4 | 2 | c | z | 3
5 | 3 | a | x | 4
6 | 3 | a | x | 4
7 | 2 | a | y | 2
Where the rank count is based off the ORDER BY
in the query and I can’t figure out how to change this.
2
Answers
As far as I know there is no built in way to do this, but you can use a sub query to achieve your result
Here is what I did (ignore the bad names, its 23:30 here if it makes it more redeemable)
The sub query finds all the present
col1/2/3
combinations and assigns them their lowest ranked id, from there we link those columns with the outer query ones and we do adense_rank
sort based on therank_id
, oh and also sort them by id so we get them in order.Feel free to play with it here
Also as a footnote you dont need to give a table allias since pgSQL-16, so if you are running that omit pg_sucks
You only need to change to
ORDER BY
of theDENSE_RANK
:see: DBFIDDLE