#Day23-MYSQL(JOIN 심화, 서브쿼리, ANSI 조인, OUTER JOIN)

D0-$ANG ₩0N·2025년 12월 8일
post-thumbnail

1. ANSI JOIN과 기존 조인 방식의 차이

1-2.기존 조인 방식

조인 조건과 일반 조건을 모두 WHERE절에 썼다.

조인 조건과 필터 조건이 섞여 있어서 가독성이 떨어진다.

SELECT e.emp_name, d.dept_name
FROM employees e, departments d
WHERE e.dept_id = d.dept_id
AND e.salary >= 3000;

1-3.ANSI JOIN 방식

조인 조건은 ON으로 분리한다.

일반 조건은 WHERE로 분리한다.

구조가 명확하고 유지보수에 유리하다.

SELECT e.emp_name, d.dept_name
FROM employees e
JOIN departments d
    ON e.dept_id = d.dept_id
WHERE e.salary >= 3000;

2. 서브쿼리(Subquery)와 Inline View

Inline View 활용

SELECT 결과를 임시 테이블처럼 사용한다.

SELECT a.emp_name, d.dept_name
FROM (
    SELECT emp_name, salary, dept_id
    FROM employees
    WHERE salary >= 3000
) a
JOIN departments d
    ON a.dept_id = d.dept_id;

필터된 데이터를 먼저 줄여 놓고 조인을 하면 효율적이다.

과거에는 성능 차이가 컸지만, 최근 DBMS는 자동 최적화를 수행하여 큰 차이가 줄어들었다.

3. 조인 우선순위와 성능

조인 기본 흐름

두 테이블의 모든 조합을 만든다 (Cartesian Product)

조건을 이용해 필터링한다

그렇기 때문에 "먼저 줄이고 조인" 방식이 논리적으로 더 빠르다.

하지만 현대 DB 엔진은 SQL을 분석해 더 빠른 실행 계획으로 자동 변환한다.

4. OUTER JOIN의 핵심 개념

Inner Join의 문제점

양쪽에서 매칭되지 않는 데이터는 제거된다.

예: 매니저가 없는 직원(스티븐 킹)은 결과에서 사라진다.

SELECT e.emp_name, m.emp_name
FROM employees e
JOIN employees m
    ON e.manager_id = m.employee_id;

여기서 매니저가 NULL인 직원은 나오지 않는다.

.

5. ANSI OUTER JOIN

5-2.Left Outer Join

왼쪽 테이블 기준으로 모두 나온다.

SELECT e.emp_name, m.emp_name
FROM employees e
LEFT JOIN employees m
    ON e.manager_id = m.employee_id;

스티븐 킹 같은 매니저 없는 직원도 NULL과 함께 나온다.

5-3.Right Outer Join

오른쪽 테이블 기준으로 모두 나온다.

SELECT e.emp_name, m.emp_name
FROM employees e
RIGHT JOIN employees m
    ON e.manager_id = m.employee_id;

5-4.Full Outer Join

양쪽 데이터 모두를 유지하는 방식
(Oracle은 지원, MySQL은 지원 안 함)

MySQL에서는 다음처럼 해결한다.

SELECT ...
FROM A
LEFT JOIN B ON ...

UNION

SELECT ...
FROM A
RIGHT JOIN B ON ...;

6. Self Join

직원 테이블을 두 번 불러서
직원과 그 직원의 매니저를 연결할 때 사용한다.

SELECT e.emp_name,
       m.emp_name AS manager_name
FROM employees e
LEFT JOIN employees m
    ON e.manager_id = m.employee_id;

같은 테이블을 두 번 사용하므로 반드시 별칭이 필요하다.

e는 직원, m은 매니저 역할을 한다.

7. Outer Join이 필요한 이유

Inner Join은 "공통 부분"만 보여준다.
이 개념을 삼각형과 원이 겹치는 영역으로 비유했다.

Outer Join은 "겹치지 않는 부분까지 포함"하는 확장된 조인이다.
현실 데이터에서는 누락된 값 때문에 데이터 손실이 자주 발생하므로
Outer Join 사용이 매우 중요하다.

8. LEFT / RIGHT / FULL OUTER JOIN 비교

종류 기준 테이블 누락 허용 방향
LEFT OUTER JOIN 왼쪽 오른쪽 누락 허용
RIGHT OUTER JOIN 오른쪽 왼쪽 누락 허용
FULL OUTER JOIN 양쪽 양쪽 누락 허용
10. JOIN 문제 실습 개념

직원 이름과 부서명 조회

직원 이름과 매니저 이름 조회

직원 이름과 직무(job_title) 조회

부서장(매니저)의 이름과 부서 이름 조회

서브쿼리로 급여 3000 이상인 사람만 필터링 후 부서명 조인

GROUP BY와 JOIN을 합쳐 부서별 급여 총합 구하기

이 과정에서 다음을 배움:

GROUP BY 이후 HAVING

JOIN과 GROUP BY 조합

Inline View 사용

ANSI JOIN 권장 이유

9. OUTER JOIN을 실제로 많이 쓰는 이유

현실 데이터에서 NULL이 매우 많기 때문이다.

일부 테이블에 없는 값 때문에 필요한 데이터가 빠지지 않도록 하기 위해 사용한다.

특히 업무 환경에서는 Left Outer Join이 가장 많이 사용된다.

SQL 강의 요약 (제약조건, ENUM, 외래키, 조인, 인덱스, 트랜잭션, 백업 등)

10. 제약조건과 컬럼 생성 규칙

테이블 컬럼을 만들 때 아무 제약조건도 주지 않으면 기본적으로 NULL 허용 상태로 생성된다.

대표적인 제약조건:

PRIMARY KEY

AUTO_INCREMENT

NOT NULL

UNIQUE

DEFAULT 값

ON UPDATE 자동 갱신 등

예: 날짜 컬럼을 자동 기록하고 싶을 때

created TIMESTAMP DEFAULT NOW(),
updated TIMESTAMP DEFAULT NOW() ON UPDATE NOW()

11. ENUM 타입

특정 값만 입력되도록 제한하고 싶을 때 사용.

성별처럼 제한된 문자열에 유용.

gender ENUM('M','F') NOT NULL

선언된 값 외의 문자는 입력할 수 없다.

12. 외래키(Foreign Key) 개념

A 테이블이 B 테이블을 참조할 때 사용한다.

예: 주문(order)은 반드시 존재하는 메뉴(menu)의 id를 참조해야 한다.

FOREIGN KEY (menu_id) REFERENCES menu(id)

ON DELETE CASCADE
부모 메뉴가 삭제되면 해당 메뉴를 참조하고 있는 주문 내역도 자동으로 삭제된다.

ON DELETE RESTRICT (기본값)
참조 중이면 삭제 불가.

13. 외래키가 필요한 이유

데이터 무결성을 유지하기 위해.

메뉴번호 10이 존재하지 않는데 주문 테이블에 menu_id = 10 이 들어오면 안 된다.

14. 조인 JOIN 정리

INNER JOIN

양쪽 테이블에 모두 존재하는 데이터만 나온다.

LEFT OUTER JOIN

왼쪽 테이블 기준으로 왼쪽 데이터는 전부 나오고 오른쪽은 맞는 것만 나온다.

RIGHT OUTER JOIN

오른쪽 기준.

FULL OUTER JOIN

양쪽 데이터 모두 포함.

MySQL은 FULL OUTER JOIN을 지원하지 않는다.

대신 UNION 을 활용한다.

SELECT ... FROM A LEFT JOIN B ...
UNION
SELECT ... FROM A RIGHT JOIN B ...

외래키가 잘못되면 특정 데이터가 조인에서 사라지는 현상이 발생할 수 있다.
이런 현상을 막기 위해 OUTER JOIN을 사용한다.

15. 인덱스 INDEX

WHERE 조건에서 자주 조회되는 컬럼에 인덱스를 걸면 속도가 수십~수백배 빨라질 수 있다.

예:

CREATE INDEX idx_name ON employees(first_name);

주의:

LIKE '%문자' 형태는 인덱스를 거의 활용하지 못한다.

'=' 혹은 LIKE '문자%' 에서 효과가 가장 크다.

16. VIEW (뷰)

복잡한 JOIN 쿼리를 매번 쓰기 번거로울 때, SELECT 결과를 이름으로 저장해두는 가상 테이블.

데이터 자체가 저장되는 것이 아니라 SELECT 문이 저장되는 개념.

예:

CREATE VIEW v_emp_dept AS
SELECT e.name, d.department_name
FROM employees e
JOIN departments d ON e.dept_id = d.id;

17. 트랜잭션(Transaction)

여러 SQL 작업을 하나의 작업 단위로 묶는 개념.

모두 성공해야만 commit, 중간에 하나라도 실패하면 rollback.

예: 은행 계좌 처리

잔액 읽기

금액 빼기

거래기록 쓰기

마지막에 commit
중간에 에러 → rollback

기본 흐름:

START TRANSACTION;
UPDATE ...;
INSERT ...;
DELETE ...;
COMMIT; 또는 ROLLBACK;

오토커밋이 켜져 있으면 매 SQL 실행마다 자동 커밋돼서 롤백이 불가능해진다.
실제 서비스 개발에서는 autocommit을 끄고 수동 트랜잭션을 사용한다.

18. DELETE, TRUNCATE, DROP 차이

DELETE

데이터만 삭제.

롤백 가능.

WHERE 조건으로 특정 데이터만 삭제 가능.

TRUNCATE

테이블 데이터를 모두 삭제하지만 구조는 남음.

롤백 불가능.

DROP

테이블 자체 삭제 (구조 + 데이터)

롤백 불가능.

Q: DROP 했는데 왜 테이블 있다고 뜨지?
A: DROP한 테이블이 아니라 다른 DB에 같은 이름이 있거나, 테이블을 다시 만들었는데 구조가 다르게 들어가 있을 수 있음. SHOW TABLES로 실제 존재 여부 확인 필요.

19. 백업 EXPORT / IMPORT

MySQL Workbench의 Export 기능을 사용하면 해당 DB 전체 스키마와 데이터를 SQL 파일로 저장할 수 있다.

Import 하면 이 파일을 그대로 읽어서 DB를 복구한다.

백업 파일은 CREATE TABLE, INSERT문 등이 모두 포함된다.

20. 시퀀스(sequence)

Oracle은 auto increment 기능이 없어 sequence를 사용한다.

MySQL은 오토 인크리먼트만으로 충분해서 sequence가 필요 없다.

21. 실무에서의 트랜잭션 처리 예

의사코드 예:

START TRANSACTION;

TRY:
INSERT order ...
INSERT sales ...
COMMIT;

EXCEPT:
ROLLBACK;

반드시 세트로 성공해야 하는 작업에 사용.

실패한 경우 데이터 불일치를 막는다.

profile
Start Change Up

0개의 댓글