[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

그럼 전 이만.