employees 테이블: 직원 정보를 저장
| 컬럼명 | 데이터 타입 | 설명 |
|------------|-------------|----------------|
| emp_id | INT | 직원 ID |
| emp_name | VARCHAR | 직원 이름 |
| dept_id | INT | 부서 ID |
departments 테이블: 부서 정보를 저장
| 컬럼명 | 데이터 타입 | 설명 |
|------------|-------------|----------------|
| dept_id | INT | 부서 ID |
| dept_name | VARCHAR | 부서 이름 |
salaries 테이블: 급여 정보를 저장
| 컬럼명 | 데이터 타입 | 설명 |
|------------|-------------|----------------|
| emp_id | INT | 직원 ID |
| salary | DECIMAL | 급여 |
| salary_date| DATE | 급여 지급일 |
SELECT
e.emp_name, -- 직원 이름
d.dept_name, -- 부서 이름
s.salary -- 급여
FROM
employees e -- 직원 테이블
JOIN
departments d -- 부서 테이블
ON e.dept_id = d.dept_id -- 부서 ID로 조인
JOIN
salaries s -- 급여 테이블
ON e.emp_id = s.emp_id -- 직원 ID로 조인
WHERE
s.salary_date = ( -- 가장 최근 급여 정보만 선택
SELECT MAX(salary_date)
FROM salaries
WHERE emp_id = e.emp_id
)
ORDER BY
e.emp_name; -- 직원 이름 기준으로 정렬
쿼리 실행 결과로 예상되는 테이블은 다음과 같습니다:
emp_name | dept_name | salary |
---|---|---|
Alice | HR | 5000 |
Bob | IT | 6000 |
Charlie | IT | 5500 |
Dave | Marketing | 4800 |
이 예시에서는 employees
, departments
, salaries
세 테이블을 조인하여 직원 이름, 부서명, 급여 정보를 출력했습니다. 결과는 직원 이름을 기준으로 오름차순으로 정렬되었습니다.
WHERE
s.salary_date = ( -- 가장 최근 급여 정보만 선택
SELECT MAX(salary_date)
FROM salaries
WHERE emp_id = e.emp_id
)
에선 select가 employee 테이블의 행 개수만큼 실행되고, 한 번에 하나의 행만 반환한다.
이렇듯 한 번에 하나의 행만 반환하는 서브쿼리를 스칼라 서브쿼리 라고한다.
따라서 employee의 행이 많으면 성능적으로 부담이 될 수 있어 서 group by와 join을 사용해 아래와 같이 수행하는 것이 더 효과적이다.
SELECT e.emp_id, e.emp_name, d.dept_name, s.salary
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
JOIN salaries s ON e.emp_id = s.emp_id
JOIN (
SELECT emp_id, MAX(salary_date) AS max_date
FROM salaries
GROUP BY emp_id
) latest_salary ON s.emp_id = latest_salary.emp_id AND s.salary_date = latest_salary.max_date;