HR 데이터를 분석할 때, 단일 테이블로 할 수 있는 일은 생각보다 많지 않다. 실무에서 다루는 데이터는 대부분 서로 연관된 여러 테이블로 구성되어 있고, 그 관계를 제대로 연결해야 의미 있는 분석이 가능하다. 나는 HR 데이터를 정교하게 분석할 수 있는 사람이 되고 싶다. 그래서 오늘은 SQL에서 가장 강력한 기능 중 하나인 JOIN과, 데이터를 요약하고 집계할 수 있는 GROUP BY, HAVING 절을 활용해 HR 데이터를 분석하는 방법을 정리해본다.
HR 데이터 분석, 왜 JOIN이 중요한가?
예를 들어보자. '성과평가 점수가 가장 높은 부서는 어디인가?'라는 질문에 답하려면 단순히 성과 테이블만으로는 부족하다. 평가점수는 performance 테이블에 있고, 부서 정보는 employees 테이블에 있기 때문이다. 이때 필요한 것이 바로 JOIN이다.
SELECT d.dept_name, AVG(p.score) AS avg_score
FROM employees e
JOIN performance p ON e.emp_id = p.emp_id
JOIN departments d ON e.dept_id = d.dept_id
GROUP BY d.dept_name
ORDER BY avg_score DESC;
이 쿼리는 직원과 성과, 부서 테이블을 JOIN하여 부서별 평균 평가점수를 구한다. 단순하지만 강력하다. 데이터를 어떻게 연결하느냐에 따라 인사이트가 바뀌고, 결과의 활용도도 완전히 달라진다.
실제로 나는 부트캠프에서 성과와 교육 데이터를 함께 분석할 일이 있었는데, 테이블을 JOIN하지 않으면 교육을 받은 직원이 성과에 어떤 영향을 받았는지 확인조차 할 수 없었다. 그때 처음 JOIN의 진짜 가치를 느낄 수 있었다.
다양한 JOIN 유형과 HR 분석 적용
JOIN에는 INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN 등 여러 유형이 있다. 특히 HR 데이터 분석에서는 각 유형마다 용도가 다르다.
# LEFT JOIN으로 교육을 받지 않은 직원 찾기
SELECT e.emp_id, e.name, t.training_id
FROM employees e
LEFT JOIN training_history t ON e.emp_id = t.emp_id
WHERE t.training_id IS NULL;
이전 HR 업무를 하면서 교육 참여율을 높이기 위해 미참여자를 찾아야 했던 일이 있었다. 그때는 엑셀로 일일이 대조했지만, LEFT JOIN을 알았더라면 얼마나 시간이 절약됐을까. 부트캠프를 통해 이런 기술을 배우면서 실무 적용성에 큰 기대를 갖게 됐다.
GROUP BY와 HAVING으로 인사이트 뽑아내기
JOIN으로 데이터를 연결했다면, 이제는 데이터를 집계해야 한다. 그때 사용하는 것이 GROUP BY와 HAVING이다.
예를 들어 '교육을 3회 이상 이수한 직원들의 평균 성과점수를 보고 싶다'고 하자.
SELECT e.emp_id, COUNT(t.training_id) AS training_count, AVG(p.score) AS avg_score
FROM employees e
JOIN training_history t ON e.emp_id = t.emp_id
JOIN performance p ON e.emp_id = p.emp_id
GROUP BY e.emp_id
HAVING COUNT(t.training_id) >= 3;
여기서 핵심은 GROUP BY로 직원 단위로 묶고, HAVING 절로 조건을 걸어주는 것이다. WHERE은 집계 전에, HAVING은 집계 후 필터링이라는 점도 기억해두면 좋다.
HR 데이터를 이렇게 집계하는 방식은 실무에서 굉장히 유용하다.
예를 들어
- 교육 이수 횟수가 많은 직원은 성과가 높은가?
- 근속연수가 긴 직원은 평가 등급이 높은가?
- 부서별 이직률이 높은 곳은 어디인가?
이런 질문은 GROUP BY와 HAVING을 적절히 활용하면 답을 도출할 수 있다.
복합 분석 사례: 교육 투자 대비 성과 분석
여러 JOIN과 집계 함수를 조합하면 더 강력한 분석이 가능하다.
# 교육 과정별 참여자 수, 평균 성과 점수, 비용 효율성 분석
SELECT t.training_name,
COUNT(DISTINCT e.emp_id) as participant_count,
AVG(p.score) as avg_score,
SUM(t.cost) as total_cost,
SUM(t.cost)/COUNT(DISTINCT e.emp_id) as cost_per_employee
FROM training_catalog tc
JOIN training_history t ON tc.training_id = t.training_id
JOIN employees e ON t.emp_id = e.emp_id
JOIN performance p ON e.emp_id = p.emp_id
WHERE t.completion_date BETWEEN '2024-01-01' AND '2024-12-31'
GROUP BY t.training_name
ORDER BY avg_score DESC;
이런 분석은 "어떤 교육이 비용 대비 효과적인가"를 보여준다. HR 부서에서 교육 예산을 배정할 때 이런 데이터가 있으면 의사결정이 훨씬 쉬워질 것이다.
내가 직접 만들어보고 싶은 분석 시나리오
JOIN과 GROUP BY를 활용해, 나는 아래와 같은 HR 분석을 해보고 싶다.
- 교육 이수자 중 고성과자 비율이 높은 부서 찾기 → 교육 성과의 효과를 부서 단위로 검토할 수 있다.
- 입사 연차와 평가 등급 간의 관계 → 신입과 고참의 성과 차이를 데이터로 확인해보고 싶다.
- 근태점수와 이직률 관계 분석 → 근무 태도와 이직 간의 연관성을 파악할 수 있다.
- 부서별 평가점수 분포 비교 → 특정 부서에 편향된 평가가 있는지 점검할 수 있다.
이런 분석을 구현하기 위해서는 데이터를 잘 설계하는 것뿐 아니라, SQL로 연결하고 요약하는 스킬이 반드시 필요하다.
나는 앞으로 이런 분석을 하나씩 구현해보며, 포트폴리오에 담을 수 있는 실전 예제를 만들어갈 계획이다.
마치며
SQL은 단순한 쿼리 언어가 아니라, 데이터 사이의 관계를 이해하고 연결하는 사고력의 도구다. HR 데이터를 깊이 있게 이해하고 싶다면 JOIN은 기본, GROUP BY와 HAVING은 필수다. 나는 단순한 데이터 정리자가 아니라, 데이터를 통해 조직의 흐름과 문제를 읽어내는 분석가가 되고 싶다.
앞으로는 실제 HR 가상 데이터를 구성해, 직원-교육-성과 데이터를 직접 JOIN하여 분석을 시도해볼 예정이다. SQL은 복잡한 분석이 아니라, 질문을 정제하고 해답을 끌어내는 과정이다. 그 질문의 깊이를 더하고, 해답의 질을 높일 수 있는 HR 애널리스트로 성장하겠다.
'HR애널리틱스 기록' 카테고리의 다른 글
[18일차] 실무 HR 데이터로 SQL 쿼리 작성하기 – 이직률 예측 분석 (5) | 2025.05.18 |
---|---|
[17일차] 실무형 HR 보고서, 서브쿼리와 뷰로 자동화하는 법 (0) | 2025.05.17 |
[15일차] 파이썬으로 HR 데이터 분석 아이디어 3가지 (2) | 2025.05.15 |
[14일차] HR 대시보드 기획안: 태블로로 시각화한다면 (0) | 2025.05.14 |
[13일차] HR 시각화 툴 비교: 파워 BI vs 태블로 (2) | 2025.05.13 |