본문 바로가기
개발/오라클

오라클 RANK 심화 - RANK() WITHIN GROUP(), RANK() OVER(), ROW_NUMBER() OVER(), DENSE_RANK()

by 루 프란체 2018. 2. 18.

ORDER BY SALARY DESC 의 그룹에서 3,000 의 순위는?


기본 문법 : RANK(순위를 구할 컬럼 혹은 값) WITHIN GROUP(ORDER BY 기준이 될 컬럼 [정렬값])


값 대신 컬럼명을 이용해 전체적인 순위를 구할 수도 있다.

SELECT RANK(3000) WITHIN GROUP(ORDER BY SALARY DESC) as DESC_RANK FROM EMPLOYEES
DESC_RANK : 82

SELECT RANK(3000) WITHIN GROUP(ORDER BY SALARY ASC) as ASC_RANK FROM EMPLOYEES
ASC_RANK : 25

제일 많은 급여를 받는 사람부터 정렬하면서 RANK 매기기


기본 문법 : RANK() OVER(ORDER BY 기준이 될 컬럼 [정렬값])

SELECT a.*, RANK() OVER(ORDER BY SALARY DESC) as RANK FROM EMPLOYEES a
salary 를 desc 정렬해 랭크를 보여준다.

※ 결과값

EMPLYEE_ID

FIRST_NAME

LAST_NAME

EMAIL

RANK

100

Steven

King

SKING

1

101

Neena

Kochhar

NKOCHHAR

2

102

Lex

De Haan

LDEHAAN

2

145

John

Russell

JRUSSEL

4

146

Karen

Partners

KPARTNER

5

201

Michael

Hartstein

MHARTSTE

6

108

Nancy

Greenberg

NGREENBE

7

205

Shelley

Higgins

SHIGGINS

7


쿼리 내에서 ORDER BY 를 따로 사용하지 않더라도 OVER() 함수 내에서 SALARY 를 기준으로 역순 정렬 했기 때문에

자동적으로 SALARY 를 기준으로 역순 정렬이 되어 표시 된다.


단, RANK() OVER() 를 사용할 때 주의점은 위의 결과값에서 보이듯이 겹치는 값이 있다면 RANK 를 건너뛰기 때문에

1, 2, 4, 5, 6, 7 의 결과값이 나오는 것을 볼 수 있다.


이런 현상을 막고 싶다면 RANK() 함수가 아닌 ROW_NUMBER() 함수를 사용하면 된다.


기본 문법 : ROW_NUMBER() OVER(ORDER BY 기준이 될 컬럼 [정렬값])

SELECT a.*, ROW_NUMBER() OVER(ORDER BY SALARY DESC) as RANK FROM EMPLOYEES a
salary 를 desc 정렬해 랭크를 보여준다.

※ 결과값

EMPLYEE_ID

FIRST_NAME

LAST_NAME

EMAIL

RANK

100

Steven

King

SKING

1

101

Neena

Kochhar

NKOCHHAR

2

102

Lex

De Haan

LDEHAAN

3

145

John

Russell

JRUSSEL

4

146

Karen

Partners

KPARTNER

5

201

Michael

Hartstein

MHARTSTE

6

108

Nancy

Greenberg

NGREENBE

7

205

Shelley

Higgins

SHIGGINS

8


단, 이 row_number() 함수 또한 맹점이 있는데 위의 결과값에 보이듯이 중복되는 값이어도 순위를 따로 매기기 때문에 

순위로 정렬할 기준들에 대한 확실한 정의가 필요하다.


그런데 사실 위의 맹점을 보완할 또 다른 함수가 존재하는데...

바로 DENSE_RANK() 함수이다.


기본 문법 : DENSE_RANK() OVER(ORDER BY 기준이 될 컬럼 [정렬값])

SELECT a.*, DENSE_RANK() OVER(ORDER BY SALARY DESC) as RANK FROM EMPLOYEES a
salary 를 desc 정렬해 랭크를 보여준다.

※ 결과값

EMPLYEE_ID

FIRST_NAME

LAST_NAME

EMAIL

RANK

100

Steven

King

SKING

1

101

Neena

Kochhar

NKOCHHAR

2

102

Lex

De Haan

LDEHAAN

2

145

John

Russell

JRUSSEL

3

146

Karen

Partners

KPARTNER

4

201

Michael

Hartstein

MHARTSTE

5

108

Nancy

Greenberg

NGREENBE

6

205

Shelley

Higgins

SHIGGINS

6


이 정도만 알아둬도 순위가 필요한 쿼리를 작성할 때 크게 어려움은 없을 것이라고 생각 된다. 이상!

댓글0