With this query:
with tbl as
(
select 1 ord, 'A' name from dual
union all
select 2 ord, 'A' name from dual
union all
select 3 ord, 'A' name from dual
union all
select 4 ord, 'B' name from dual
union all
select 5 ord, 'B' name from dual
union all
select 6 ord, 'A' name from dual
union all
select 7 ord, 'A' name from dual
union all
select 8 ord, 'C' name from dual
union all
select 9 ord, 'C' name from dual
union all
select 10 ord, 'B' name from dual
union all
select 11 ord, 'B' name from dual
union all
select 12 ord, 'B' name from dual
)
select ord, name, myrank(...)
from tbl
order by
ord;
I want to get these results:
ORD NAME MYRANK
---------- ---- ----------
1 A 1
2 A 1
3 A 1
4 B 2
5 B 2
6 A 3
7 A 3
8 C 4
9 C 4
10 B 5
11 B 5
12 B 5
Same rank for continuous equal values.
Different groups of same continuous equal values have different ranks.
Rank increases monotonically in order of "ord".
For Oracle and PostgreSQL (ultimate query for both systems is preferable).
2
Answers
From Oracle 12, you can use
MATCH_RECOGNIZE
to perform row-by-row pattern matching:In all versions, you can use the
LAG
andSUM
analytic functions to output the same:Which, for the sample data, both output:
The second query also works in PostgreSQL.
Oracle fiddle PostgreSQL fiddle
This works for either RDBMS:
Postgres fiddle
Oracle fiddle
Notably,
count()
only counts not-null values, andCounting the number of changes in the
name
column generates the desired group numbers.Optimized for Postgres:
Related: