문제 설명
HR_DEPARTMENT 테이블은 회사의 부서 정보를 담은 테이블입니다. HR_DEPARTMENT 테이블의 구조는 다음과 같으며 DEPT_ID, DEPT_NAME_KR, DEPT_NAME_EN, LOCATION은 각각 부서 ID, 국문 부서명, 영문 부서명, 부서 위치를 의미합니다.Column name | Type | Nullable |
DEPT_ID | VARCHAR | FALSE |
DEPT_NAME_KR | VARCHAR | FALSE |
DEPT_NAME_EN | VARCHAR | FALSE |
LOCATION | VARCHAR | FLASE |
HR_EMPLOYEES 테이블은 회사의 사원 정보를 담은 테이블입니다. HR_EMPLOYEES 테이블의 구조는 다음과 같으며 EMP_NO, EMP_NAME, DEPT_ID, POSITION, EMAIL, COMP_TEL, HIRE_DATE, SAL은 각각 사번, 성명, 부서 ID, 직책, 이메일, 전화번호, 입사일, 연봉을 의미합니다.Column name | Type | Nullable |
EMP_NO | VARCHAR | FALSE |
EMP_NAME | VARCHAR | FALSE |
DEPT_ID | VARCHAR | FALSE |
POSITION | VARCHAR | FALSE |
EMAIL | VARCHAR | FALSE |
COMP_TEL | VARCHAR | FALSE |
HIRE_DATE | DATE | FALSE |
SAL | NUMBER | FALSE |
HR_GRADE 테이블은 2022년 사원의 평가 정보를 담은 테이블입니다. HR_GRADE의 구조는 다음과 같으며 EMP_NO, YEAR, HALF_YEAR, SCORE는 각각 사번, 연도, 반기, 평가 점수를 의미합니다.Column name | Type | Nullable |
EMP_NO | VARCHAR | FALSE |
YEAR | NUMBER | FALSE |
HALF_YEAR | NUMBER | FALSE |
SCORE | NUMBER | FALSE |
예시
예를 들어
HR_DEPARTMENT 테이블이 다음과 같고DEPT_ID | DEPT_NAME_KR | DEPT_NAME_EN | LOCATION |
D0001 | 법무팀 | Law Dep | 그렙타워 4층 |
D0002 | 인사팀 | Human resources | 그렙타워 4층 |
D0003 | 총무팀 | General Affairs | 그렙타워 4층 |
HR_EMPLOYEES 테이블이 다음과 같고EMP_NO | EMP_NAME | DEPT_ID | POSITION | EMAIL | COMP_TEL | HIRE_DATE | SAL |
2017002 | 정호식 | D0001 | 팀장 | 031-8000-1101 | 2017-03-01 | 65000000 | |
2018001 | 김민석 | D0001 | 팀원 | 031-8000-1102 | 2018-03-01 | 60000000 | |
2019001 | 김솜이 | D0002 | 팀장 | 031-8000-1106 | 2019-03-01 | 60000000 | |
2020002 | 김연주 | D0002 | 팀원 | 031-8000-1107 | 2020-03-01 | 53000000 | |
2020005 | 양성태 | D0003 | 팀원 | 031-8000-1112 | 2020-03-01 | 53000000 |
HR_GRADE 테이블이 다음과 같을 때EMP_NO | YEAR | HALF_YEAR | SCORE |
2017002 | 2022 | 1 | 92 |
2018001 | 2022 | 1 | 89 |
2019001 | 2022 | 1 | 94 |
2020002 | 2022 | 1 | 90 |
2020005 | 2022 | 1 | 92 |
2017002 | 2022 | 2 | 84 |
2018001 | 2022 | 2 | 89 |
2019001 | 2022 | 2 | 81 |
2020002 | 2022 | 2 | 91 |
2020005 | 2022 | 2 | 81 |
다음과 같이 평가 점수가 가장 높은 사원 정보를 출력해야 합니다.
SCORE | EMP_NO | EMP_NAME | POSITION | EMAIL |
181 | 202002 | 김연주 | 팀원 |
코드
SELECT
HG.SCORE,
HG.EMP_NO,
HE.EMP_NAME,
HE.POSITION,
HE.EMAIL
FROM
(
SELECT
EMP_NO,
SUM(SCORE) AS SCORE
FROM
HR_GRADE
WHERE
YEAR = 2022
GROUP BY
EMP_NO
ORDER BY
SCORE DESC
LIMIT
1
) AS HG
JOIN
HR_EMPLOYEES HE
ON
HG.EMP_NO = HE.EMP_NO;
'동점자 처리'와 '가독성/확장성' 측면에서 개선 코드
/*
[최적화 방식: Window Function 활용]
1. WITH 절(CTE)을 사용하여 연도별 사원 점수 총합과 순위를 미리 계산합니다.
2. RANK() 함수를 사용하여 동점자 발생 시에도 1등을 모두 포착할 수 있도록 합니다.
3. 메인 쿼리에서는 순위가 1인 사원만 필터링하여 조인합니다.
*/
WITH EMP_TOTAL_SCORE AS (
SELECT
EMP_NO,
SUM(SCORE) AS TOTAL_SCORE,
RANK() OVER (ORDER BY SUM(SCORE) DESC) AS RNK
FROM
HR_GRADE
WHERE
YEAR = 2022
GROUP BY
EMP_NO
)
SELECT
TS.TOTAL_SCORE AS SCORE,
TS.EMP_NO,
HE.EMP_NAME,
HE.POSITION,
HE.EMAIL
FROM
EMP_TOTAL_SCORE TS
INNER JOIN
HR_EMPLOYEES HE
ON
TS.EMP_NO = HE.EMP_NO
WHERE
TS.RNK = 1;- 만약 1등이 여러 명(동점자)일 경우 한 명만 출력되는 논리적 맹점이 있습니다. 실제 현업이나 코딩 테스트에서는 동점자를 모두 출력해야 하는 경우가 많습니다.
Share article