我怎样才能像 mysql 这样在 oracle 中写排名 sql
how can i write rank sql in oracle like mysql
我的 sql 段在 mysql:
SELECT t.*,@r1:=@r1+1 r1,@r:=IF(@v=score OR(@v IS NULL AND score IS NULL),@r,@r1) rank,@v:=score v1
FROM(SELECT @r :=0) a,(SELECT @r1 :=0) b,(SELECT @v:=NULL) v,(SELECT id,score FROM exam_inst
WHERE eid = '1161918326813872128' AND type = 2 GROUP BY dealer
ORDER BY i_level DESC,create_date DESC) t ORDER BY score DESC
我想在 Oracle 中编写相同的查询 sql,我该怎么做?
table:
A B
c1 a
c1 b
c1 a
c2 a
c2 a
c2 b
查询结果:
A B R
c1 a 1
c1 b 2
c1 a 3
c2 a 1
c2 a 1
c2 b 3
使用RANK
解析函数:
SELECT t.*,
RANK() OVER ( PARTITION BY a ORDER BY b ) AS r
FROM table_name t;
或您的示例数据:
CREATE TABLE table_name ( a, b ) AS
SELECT 'c1', 'a' FROM DUAL UNION ALL
SELECT 'c1', 'b' FROM DUAL UNION ALL
SELECT 'c1', 'a' FROM DUAL UNION ALL
SELECT 'c2', 'a' FROM DUAL UNION ALL
SELECT 'c2', 'a' FROM DUAL UNION ALL
SELECT 'c2', 'b' FROM DUAL;
这输出:
A | B | R
:- | :- | -:
c1 | a | 1
c1 | a | 1
c1 | b | 3
c2 | a | 1
c2 | a | 1
c2 | b | 3
db<>fiddle here
更新
I just want to compare adjacent rows,i do not care about how many 'a'
SQL 中的行未排序;所以你需要另一列来存储行的顺序:
CREATE TABLE table_name ( a, b, c ) AS
SELECT 'c1', 'a', 1 FROM DUAL UNION ALL
SELECT 'c1', 'b', 2 FROM DUAL UNION ALL
SELECT 'c1', 'a', 3 FROM DUAL UNION ALL
SELECT 'c2', 'a', 1 FROM DUAL UNION ALL
SELECT 'c2', 'a', 2 FROM DUAL UNION ALL
SELECT 'c2', 'b', 3 FROM DUAL;
这将找到行的密集排名:
SELECT a,
b,
c,
SUM( has_changed ) OVER ( PARTITION BY a ORDER BY c ) AS r
FROM (
SELECT t.*,
CASE
WHEN b = LAG( b ) OVER ( PARTITION BY a ORDER BY c )
THEN 0
ELSE 1
END AS has_changed
FROM table_name t
)
ORDER BY a, c;
输出:
A | B | C | R
:- | :- | -: | -:
c1 | a | 1 | 1
c1 | b | 2 | 2
c1 | a | 3 | 3
c2 | a | 1 | 1
c2 | a | 2 | 1
c2 | b | 3 | 2
如果您想要(稀疏)排名,那么您可以获取之前的输出并对其应用 RANK
分析函数:
SELECT a,
b,
c,
RANK() OVER ( PARTITION BY a ORDER BY r ) AS r
FROM (
SELECT a,
b,
c,
SUM( has_changed ) OVER ( PARTITION BY a ORDER BY c ) AS r
FROM (
SELECT t.*,
CASE
WHEN b = LAG( b ) OVER ( PARTITION BY a ORDER BY c )
THEN 0
ELSE 1
END AS has_changed
FROM table_name t
)
)
ORDER BY a, c;
输出:
A | B | C | R
:- | :- | -: | -:
c1 | a | 1 | 1
c1 | b | 2 | 2
c1 | a | 3 | 3
c2 | a | 1 | 1
c2 | a | 2 | 1
c2 | b | 3 | 3
您还可以使用 MATCH_RECOGNIZE
来比较连续的行:
SELECT a,
b,
c,
dense_rank,
RANK() OVER( PARTITION BY a ORDER BY dense_rank ) AS sparse_rank
FROM table_name
MATCH_RECOGNIZE (
PARTITION BY a
ORDER BY c
MEASURES MATCH_NUMBER() AS dense_rank
ALL ROWS PER MATCH
PATTERN (FIRST_ROW EQUAL_ROWS*)
DEFINE EQUAL_ROWS AS EQUAL_ROWS.b = PREV(EQUAL_ROWS.b)
)
输出:
A | B | C | DENSE_RANK | SPARSE_RANK
:- | :- | -: | ---------: | ----------:
c1 | a | 1 | 1 | 1
c1 | b | 2 | 2 | 2
c1 | a | 3 | 3 | 3
c2 | a | 1 | 1 | 1
c2 | a | 2 | 1 | 1
c2 | b | 3 | 2 | 3
db<>fiddle here
我的 sql 段在 mysql:
SELECT t.*,@r1:=@r1+1 r1,@r:=IF(@v=score OR(@v IS NULL AND score IS NULL),@r,@r1) rank,@v:=score v1
FROM(SELECT @r :=0) a,(SELECT @r1 :=0) b,(SELECT @v:=NULL) v,(SELECT id,score FROM exam_inst
WHERE eid = '1161918326813872128' AND type = 2 GROUP BY dealer
ORDER BY i_level DESC,create_date DESC) t ORDER BY score DESC
我想在 Oracle 中编写相同的查询 sql,我该怎么做?
table:
A B
c1 a
c1 b
c1 a
c2 a
c2 a
c2 b
查询结果:
A B R
c1 a 1
c1 b 2
c1 a 3
c2 a 1
c2 a 1
c2 b 3
使用RANK
解析函数:
SELECT t.*,
RANK() OVER ( PARTITION BY a ORDER BY b ) AS r
FROM table_name t;
或您的示例数据:
CREATE TABLE table_name ( a, b ) AS
SELECT 'c1', 'a' FROM DUAL UNION ALL
SELECT 'c1', 'b' FROM DUAL UNION ALL
SELECT 'c1', 'a' FROM DUAL UNION ALL
SELECT 'c2', 'a' FROM DUAL UNION ALL
SELECT 'c2', 'a' FROM DUAL UNION ALL
SELECT 'c2', 'b' FROM DUAL;
这输出:
A | B | R :- | :- | -: c1 | a | 1 c1 | a | 1 c1 | b | 3 c2 | a | 1 c2 | a | 1 c2 | b | 3
db<>fiddle here
更新
I just want to compare adjacent rows,i do not care about how many 'a'
SQL 中的行未排序;所以你需要另一列来存储行的顺序:
CREATE TABLE table_name ( a, b, c ) AS
SELECT 'c1', 'a', 1 FROM DUAL UNION ALL
SELECT 'c1', 'b', 2 FROM DUAL UNION ALL
SELECT 'c1', 'a', 3 FROM DUAL UNION ALL
SELECT 'c2', 'a', 1 FROM DUAL UNION ALL
SELECT 'c2', 'a', 2 FROM DUAL UNION ALL
SELECT 'c2', 'b', 3 FROM DUAL;
这将找到行的密集排名:
SELECT a,
b,
c,
SUM( has_changed ) OVER ( PARTITION BY a ORDER BY c ) AS r
FROM (
SELECT t.*,
CASE
WHEN b = LAG( b ) OVER ( PARTITION BY a ORDER BY c )
THEN 0
ELSE 1
END AS has_changed
FROM table_name t
)
ORDER BY a, c;
输出:
A | B | C | R :- | :- | -: | -: c1 | a | 1 | 1 c1 | b | 2 | 2 c1 | a | 3 | 3 c2 | a | 1 | 1 c2 | a | 2 | 1 c2 | b | 3 | 2
如果您想要(稀疏)排名,那么您可以获取之前的输出并对其应用 RANK
分析函数:
SELECT a,
b,
c,
RANK() OVER ( PARTITION BY a ORDER BY r ) AS r
FROM (
SELECT a,
b,
c,
SUM( has_changed ) OVER ( PARTITION BY a ORDER BY c ) AS r
FROM (
SELECT t.*,
CASE
WHEN b = LAG( b ) OVER ( PARTITION BY a ORDER BY c )
THEN 0
ELSE 1
END AS has_changed
FROM table_name t
)
)
ORDER BY a, c;
输出:
A | B | C | R :- | :- | -: | -: c1 | a | 1 | 1 c1 | b | 2 | 2 c1 | a | 3 | 3 c2 | a | 1 | 1 c2 | a | 2 | 1 c2 | b | 3 | 3
您还可以使用 MATCH_RECOGNIZE
来比较连续的行:
SELECT a,
b,
c,
dense_rank,
RANK() OVER( PARTITION BY a ORDER BY dense_rank ) AS sparse_rank
FROM table_name
MATCH_RECOGNIZE (
PARTITION BY a
ORDER BY c
MEASURES MATCH_NUMBER() AS dense_rank
ALL ROWS PER MATCH
PATTERN (FIRST_ROW EQUAL_ROWS*)
DEFINE EQUAL_ROWS AS EQUAL_ROWS.b = PREV(EQUAL_ROWS.b)
)
输出:
A | B | C | DENSE_RANK | SPARSE_RANK :- | :- | -: | ---------: | ----------: c1 | a | 1 | 1 | 1 c1 | b | 2 | 2 | 2 c1 | a | 3 | 3 | 3 c2 | a | 1 | 1 | 1 c2 | a | 2 | 1 | 1 c2 | b | 3 | 2 | 3
db<>fiddle here