database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
ㆍPostgreSQL
Firebird
Oracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
PostgreSQL Q&A 5007 게시물 읽기
No. 5007
포스터에서 순위를 구할려고 합니다.[질문수정]
작성자
졸리
작성일
2003-10-19 18:09ⓒ
2003-10-20 07:54ⓜ
조회수
3,255

대충 테이블이 이렇게 되어있다고 하고요

ID 점수

a 3

b 10

c 5

d 5

쿼리를 해서 순위값을 알고 싶거든요. 이런식으로

순위 ID 점수

1 b 10

2 c 5

2 d 5

3 a 3

이런식으로 점수 높은 순으로 소트하면서 같은 점수는 같은 순위로 하면서

순위값을 알고 싶습니다. 제가 DB 초보라서 힘드네요. 급해서 그러는데 고수님들이 Sql 문을 가르쳐 주시면 감사하겠습니다.

 

==============================================================

게시판의 글중 위의 순위(랭킹)을 매기는것과 동일합니다.

 

이런경우는 새로운 데이터가 입력된후 다시 검색을 하면 시퀀스번호과 (이전이데이터가 6개라 1~6 이 사용되었다면)

7부터 13 까지 다시 생성됩니다.

 

 

 

오라클 함수의 경우

select  RANK() OVER(ORDER BY SUM(A.TOTAL) DESC) as 순위  ,SUM(A.TOTAL) as 총점

           ^^^^^^^^^^^^^^

from,,,,,

where,,,,,

와 같이 사용되어 랭킹을 부여하였지만, pgSQL에서는 OVER 함수가 지원되지 않고 있다고 알고 있습니다.

 

[[질문]]

점수에 대한 랭킹을 부여하고 싶습니다. 오라클함수의  rank() 함수를  pgSQL 의 대체함수는 어떤것이 있을까요?

 

 

이 글에 대한 댓글이 총 4건 있습니다.

무엇을 순위함수라 하는지요?

구체적으로 함수라 함은, 입력인자와 출력결과 있어야할 것같네요. 그 함수의 입출력 모습을 알려주십시오.

 

김상기(ioseph)님이 2003-10-19 23:18에 작성한 댓글입니다.

function 하나를 만들어야겠네요.

범용 프로타입을 하나 지정하고,

시간나면 한번 만들어보지요.

 

김상기(ioseph)님이 2003-10-21 17:03에 작성한 댓글입니다.

점심시간에 잠깐 만들어보았습니다. 범용 함수를 만드려고 했었는데, 실력이 없어서 못 만들었습니다.

사용하시려면, 아래 예제를 참고로 함수 자체를 직접 만드셔야 할 듯 싶습니다.

새로 만들어야할 경우는,

그 순위를 매기는 필드가 숫자형이 아닌, 문자형인 경우와,

순위를 정하는 필드가 두개이상일 경우 입니다.

 

테스트 테이블

mydb=# select * from ranktest;
 no |  name  | score
----+--------+-------
  1 | 홍길동 |    70
  2 | 김철수 |    80
  3 | 나영희 |    70
  4 | 박개똥 |    60
  5 | 전천재 |   100
  6 | 오바보 |     0
  7 | 아무개 |    90
  8 | 이순희 |    80
(8 rows)

 

함수 코드:

/* 순위 매기는 함수
작성일: 2003. 10. 22. (수) 14:15:46 KST
작성자: 김상기 ioseph@uri.sarang.net
저작권: 이 프로그램은 제작자의 동의 없이 무단 복제, 수정, 배포를 널리 권장합니다.
인자설명: rank( name, name, name, name, boolean)  
1.테이블
2.join될 key column
3.순위 매길 column
4.정렬방법(asc, desc)
5.순위번호의 중복(boolean 형)
*/
CREATE FUNCTION rank (name, name, name, name, boolean) RETURNS SETOF record
    AS '
DECLARE
    relname ALIAS FOR $1;
    joincolumn ALIAS FOR $2;
    sortcolumn ALIAS FOR $3;
    sorttype ALIAS FOR $4;
    isduple ALIAS FOR $5;
    ranknum int;
    row record;
    query text;
    prevval int;
    skipnum int;
BEGIN
    query := ''SELECT 0::int AS ranknum, '' || joincolumn || '', '' || sortcolumn
            || '' AS sortval FROM '' || relname
            || '' ORDER BY '' || sortcolumn || '' '' || sorttype;
    ranknum := 0;
    skipnum := 1;
    prevval := 0;
    FOR row IN EXECUTE query LOOP
        IF isduple = true THEN
            IF prevval <> row.sortval THEN
                prevval := row.sortval;
                ranknum := ranknum + skipnum;
                skipnum := 1;
            ELSE
                skipnum := skipnum + 1;
            END IF;
            row.ranknum := ranknum;
        ELSE
            ranknum := ranknum + 1;
            row.ranknum := ranknum;
        END IF;
        RETURN NEXT row;
    END LOOP;
    RETURN;
END;
'
    LANGUAGE plpgsql;

 

사용결과: (순위번호 순차적, 같은 등수 무시)

# select b.ranknum,a.*
    from ranktest a,
         (select * from rank('ranktest','no','score','desc',false)
 as t (ranknum int, no int, score int)) b 
where a.no = b.no 
order by b.ranknum;
 ranknum | no |  name  | score
---------+----+--------+-------
       1 |  5 | 전천재 |   100
       2 |  7 | 아무개 |    90
       3 |  2 | 김철수 |    80
       4 |  8 | 이순희 |    80
       5 |  1 | 홍길동 |    70
       6 |  3 | 나영희 |    70
       7 |  4 | 박개똥 |    60
       8 |  6 | 오바보 |     0
(8 rows)

사용결과: 같은 등수는 감안한 것

# select b.ranknum,a.*
from ranktest a,
(select * from rank('ranktest','no','score','desc',true)
as t (ranknum int, no int, score int)) b 
where a.no = b.no 
order by b.ranknum;
 ranknum | no |  name  | score
---------+----+--------+-------
       1 |  5 | 전천재 |   100
       2 |  7 | 아무개 |    90
       3 |  2 | 김철수 |    80
       3 |  8 | 이순희 |    80
       5 |  1 | 홍길동 |    70
       5 |  3 | 나영희 |    70
       7 |  4 | 박개똥 |    60
       8 |  6 | 오바보 |     0
(8 rows)

 

이렇게 사용되어집니다. table return function 기능의 한 예입니다.

 

문제는 join 되어야할 자료가 무지막지할 때는 속도가 꽤 떨어질 것같네요. 즉, 전체 자료가 백만건 정도인데, 순위로 50만부터 60만번까지의 리스트를 뽑는 일 같은 경우라면, 속도가 무지막지할 것같습니다.

 

김상기(ioseph)님이 2003-10-22 14:31에 작성한 댓글입니다.
이 댓글은 2003-10-22 14:32에 마지막으로 수정되었습니다.

김상기님 감사합니다.

감사의 말부터전해드리고, 구현해보겠습니다.

많은 분들이 김상기님의 글을 보고 많은도움이 되리라 믿습니다.

 

좋은하루되세요

졸리님이 2003-10-23 09:39에 작성한 댓글입니다. Edit
[Top]
No.
제목
작성자
작성일
조회
5010한 테이블의 데이터만 덤프하려는데.. 에러가 자꾸 나네요.... [1]
장현식
2003-10-21
2104
5009jdbc 연결시 다음과 같은 에러가 나는군요 . 고수님들의 가름침을? [3]
관광소~주
2003-10-20
1463
5008트리거프로시져 질문입니다. [1]
Agustin
2003-10-20
1850
5007포스터에서 순위를 구할려고 합니다.[질문수정] [4]
졸리
2003-10-19
3255
5006SQL 쿼리문 하나 만들려고 하는데... 잘 안되네여... T_T [2]
윤병훈
2003-10-17
1400
5005동시접속자수가 최고 20명 까지 입니다! 환경설정을 어떻게? [2]
박근준
2003-10-16
1478
5004덤프하면 한글이 이상하게 나오네요. [1]
김명호
2003-10-16
1479
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.017초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다