[DEV SQL] 5. [MySQL/MariaDB] Select Gruop by TOP1 (각 그룹별로 TOP 1 가져오기)


[MySQL/MariaDB]에서 각 그룹별로 TOP 1 가져오는 포스팅이다.



예제 테이블

SCORES(점수)

컬럼컬럼명
NAME학생이름
SUBJECT과목
SCORE점수


SCORES Select

NAME과목점수
김재현수학90
김재현국어71
김재현영어66
김재현사회80
박웅비수학98
박웅비국어82
박웅비영어80
박웅비사회61
정대철수학77
정대철국어67
정대철영어78
정대철사회98
정연호수학77
정연호국어86
정연호영어67
정연호사회85
………
………



개발하다 보면 각 그룹 별 TOP 1 이 필요하는 쿼리가 필요하다. 오라클인 경우 PARTITONN BY 로 각 그룹(학생) 별로 ROWNUM를 주고 조건절을 주면 된다.


Oracle에서 Select Group by TOP 1

SELECT
    S1.*
FROM
    (
    SELECT
        NAME
        , SUBJECT
        , SCORE
        , ROW_NUMBER() OVER(PARTITONN BY NAME ORDER BY NAME, SCORE) ROWNUM
    FROM
        SCORES
    )
WHERE
    RNUM = 1 -- ex) RNUM => 3



MySQL에서는 각 그룹별로 ROWNUM를 활용해서 각 그룹별로 TOP 1를 가져올 수 있다.

MySQL에서 ROWNUM

SELECT
	@ROWNUM:=@ROWNUM+1 AS ROWNUM
	, NAME
	, SUBJECT
	, SCORE
FROM 
	SCORES, (SELECT @ROWNUM:=0) R


MySQL에서 각 그룹별로 ROWNUM를 활용한 Select Group by TOP 1

SELECT
	S1.*
FROM
    (
    SELECT 
        NAME
        , SUBJECT
        , SCORE
        , CASE WHEN @GRP = NAME THEN @ROWNUM:=@ROWNUM + 1 ELSE @ROWNUM :=1 END AS ROWNUM
        , (@GRP := NAME) as dummy
    FROM
        SCORES, (select @ROWNUM:=0, @GRP:='') R 
    ORDER BY
        NAME, SCORE ASC
    ) S1
WHERE
    S1.ROWNUM = 1


위에 쿼리를 실행하면 아래와 같이 각 학생 별로 제일 높은 점수의 과목을 가져올 수 있다. 통계나 집계에서 유용하게 활용 할 수 있다.


실행결과

NAMESUBJECTSCOREROWNUM
김재현수학901
박웅비수학981
정대철사회981
정연호국어861
주형신영어851
………1
………1

그럼 전 이만.