
두 개 이상의 테이블에서 조건에 맞는 데이터를 조회하고 싶을 때 JOIN을 사용한다. 예시로 A와 B라는 테이블이 있을 때
A의 특정 조건과 B의 특정 조건을 둘 다 만족하는 데이터를 조회하는 경우 join을 사용한다.
JOIN은 두 테이블의 데이터를 조건에 따라 결합해 하나의 테이블처럼 결과를 반환한다.
이때 조건을 만족하지 않는 쪽의 컬럼 값은 NULL로 채워질 수 있다 (OUTER JOIN의 경우).
INNER JOIN: 주어진 조건을 모두 만족하는 교집합 데이터를 반환한다.
LEFT (OUTER) JOIN : 왼쪽 데이터는 모두 반환하고 오른쪽은 조건을 만족하는 데이터만 반환한다.
RIGHT (OUTER) JOIN: 오른쪽 데이터는 모두 반환하고 왼쪽 데이터는 조건을 만족하는 데이터만 반환한다.
FULL (OUTER) JOIN: 조건에 관계없이 양쪽 테이블의 모든 데이터를 반환하며, 일치하지 않는 행은 NULL로 채워진다.
CROSS JOIN: 왼쪽과 오른쪽 데이터의 모든 순서쌍을 반환한다. 조건이 따로 필요하지 않다
SELECT e.name, d.dept_name
FROM employees e
LEFT JOIN departments d
ON e.dept_id = d.id;
JOIN을 사용할 떄는 ON을 통해 JOIN의 기준이 되는 조건을 정해줄 수 있다. 기존에 사용하던 WHERE은 ON을 통해 반환된 데이터를 기준으로 필터링한다.

서브쿼리는 쿼리 안에 있는 또 다른 쿼리이다.
-- 'Sales' 부서의 ID를 가진 사원 조회
SELECT name
FROM employees
WHERE dept_id = (
SELECT dept_id
FROM departments
WHERE dept_name = 'Sales'
);
-- 모든 사원의 평균 급여를 구하고 함께 출력
SELECT name, salary,
(SELECT AVG(salary) FROM employees) AS avg_salary
FROM employees;
> -- 부서별 평균 급여를 구하고, 평균 급여 5000 이상인 부서만 조회
SELECT dept_id, avg_salary
FROM (
SELECT dept_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY dept_id
) AS sub
WHERE avg_salary >= 5000;
JOIN을 사용할 경우 두 테이블을 하나의 테이블로 합친 결과를 반환하지만 서브 쿼리는 한 쿼리의 결과를 다른 쿼리의 조건으로 사용하는 것이기 때문에 반환 값은 하나의 테이블 데이터이다.
서브쿼리를 사용해 JOIN을 대체할 수 있는 경우도 있지만, 서브쿼리가 중첩되면 성능 저하가 발생할 수 있다.
따라서 데이터량이 많고 성능이 중요한 경우에는 JOIN을 사용하는 것이 더 효율적이다.