通过此查询:
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;
我想得到这些结果:
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
连续相等的值具有相同的排名。 相同连续相等值的不同组具有不同的等级。 排名按“ord”顺序单调增加。
对于 Oracle 和 PostgreSQL(最好对两个系统进行最终查询)。
从 Oracle 12 开始,您可以使用
MATCH_RECOGNIZE
执行逐行模式匹配:
SELECT ord, name, myrank
FROM tbl
MATCH_RECOGNIZE(
ORDER BY ord
MEASURES
MATCH_NUMBER() AS myrank
ALL ROWS PER MATCH
PATTERN (same_name+)
DEFINE
same_name AS FIRST(name) = name
);
在所有版本中,您可以使用
LAG
和 SUM
分析函数来输出相同的结果:
SELECT ord,
name,
SUM(has_changed) OVER (ORDER BY ord) AS myrank
FROM (
SELECT ord,
name,
CASE
WHEN name = LAG(name) OVER (ORDER BY ord)
THEN 0
ELSE 1
END AS has_changed
FROM tbl
);
对于样本数据,两者输出:
ORD | 姓名 | 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 |