1. 데이터 삽입 (Create)
1.1 기본 INSERT 구문
INSERT 문은 테이블에 새로운 레코드를 추가할 때 사용합니다. 특정 컬럼만 지정하여 삽입하거나, 모든 컬럼의 데이터를 한 번에 넣을 수도 있습니다. MySQL에서는 INTO 키워드를 생략할 수 있지만, 표준 SQL과의 호환성을 위해 포함하는 것이 권장됩니다.
-- 특정 컬럼에만 데이터 삽입
INSERT INTO members (member_id, service_code, nickname)
VALUES (101, 5001, '테스터A');
-- 전체 컬럼 데이터 삽입 (테이블 정의 순서 준수)
INSERT INTO members
VALUES (102, 5002, '테스터B', 'test@example.com');
-- 다중 행(Bulk) 삽입 (성능 최적화에 유리)
INSERT INTO members (member_id, service_code, nickname, email)
VALUES
(103, 5003, '사용자C', 'userC@mail.com'),
(104, 5004, '사용자D', 'userD@mail.com'),
(105, 5005, '사용자E', 'userE@mail.com');
1.2 중복 키 업데이트 (ON DUPLICATE KEY UPDATE)
데이터 삽입 시 PK(기본키)나 Unique Index 충돌이 발생할 경우, 에러를 내는 대신 기존 데이터를 수정하도록 처리할 수 있습니다.
- 신규 삽입 성공:
row_count()가 1을 반환 - 기존 데이터 업데이트:
row_count()가 2를 반환 - 변경 사항 없음:
row_count()가 0을 반환
INSERT INTO members (member_id, service_code, nickname, email)
VALUES (101, 5001, '수정된닉네임', 'update@mail.com')
ON DUPLICATE KEY UPDATE
nickname = '수정된닉네임',
email = 'update@mail.com';
1.3 REPLACE 문
REPLACE INTO는 충돌 발생 시 기존 행을 삭제(DELETE)한 후 새 행을 삽입(INSERT)합니다. ON DUPLICATE KEY UPDATE와 달리 기존 데이터를 지우고 새로 쓰기 때문에 Auto Increment 값이 증가하거나 외래 키 제약 조건에 영향을 줄 수 있으므로 주의해서 사용해야 합니다.
REPLACE INTO members (service_code, nickname, email)
VALUES (6001, '신규유저', 'new@mail.com');
2. 데이터 조회 (SELECT) 기초
2.1 기본 조회 방식
SELECT *는 모든 컬럼을 가져오지만, 운영 환경에서는 네트워크 트래픽 증가와 인덱스 효율 저하를 방지하기 위해 필요한 컬럼만 명시하는 것이 좋습니다.
-- 전체 컬럼 조회 (권장되지 않음)
SELECT * FROM grade_reports;
-- 특정 컬럼 필터링 조회
SELECT student_id, student_name, math_score FROM grade_reports;
2.2 표현식 활용과 별칭(Alias)
조회 시 연산이나 함수를 적용할 수 있으며, AS 키워드를 사용하여 결과 컬럼에 이름을 붙일 수 있습니다.
-- 연산 결과에 별칭 부여
SELECT
student_name,
math_score,
(math_score + english_score + science_score) AS total_score
FROM grade_reports;
-- AS 생략 가능
SELECT
student_name 성함,
math_score 수학점수
FROM grade_reports;
2.3 결과 중복 제거 (DISTINCT)
DISTINCT를 사용하여 중복된 결과 값을 하나로 합쳐서 보여줄 수 있습니다.
-- 중복된 점수 제거 후 고유값만 출력
SELECT DISTINCT math_score FROM grade_reports;
3. 조건 필터링 (WHERE)
3.1 주요 연산자
| 연산자 | 설명 | 비고 |
|---|---|---|
>, >=, <, <= |
크기 비교 | 숫자, 문자열, 날짜 지원 |
= |
같음 | NULL 비교 시 NULL 반환 |
<=> |
NULL 안전 같음 | NULL <=> NULL 은 TRUE |
!=, <> |
다름 | NULL 비교 불가 |
BETWEEN a AND b |
범위 포함 | [a, b] 폐구간 |
IN (list) |
목록 포함 | 리스트 중 하나라도 일치하면 참 |
IS NULL |
NULL 확인 | NULL 값인 데이터만 추출 |
LIKE |
패턴 매칭 | % (0개 이상), _ (1개 문자) |
3.2 WHERE 절의 제약 사항: 별칭 사용 불가
SQL 실행 순서상 WHERE 절은 SELECT 절보다 먼저 실행됩니다. 따라서 SELECT에서 정의한 별칭(Alias)은 WHERE 절에서 인식할 수 없습니다.
-- [에러 발생 사례]
SELECT name, (math + english) AS total
FROM scores
WHERE total < 150;
-- [올바른 사례] 원본 표현식 사용
SELECT name, (math + english) AS total
FROM scores
WHERE (math + english) < 150;
4. 결과 정렬 (ORDER BY)
데이터를 오름차순(ASC, 기본값) 또는 내림차순(DESC)으로 정렬합니다. MySQL에서 NULL 값은 가장 작은 값으로 취급되어 ASC 시 가장 먼저 등장합니다.
-- 다중 조건 정렬: 수학 점수 내림차순 후, 동점자는 이름 순 정렬
SELECT name, math_score, english_score
FROM grade_reports
ORDER BY math_score DESC, name ASC;
-- SELECT 별칭 사용 가능 (SELECT 이후에 실행되므로)
SELECT name, (math + english) AS total
FROM scores
ORDER BY total DESC;
5. 결과 제한 및 페이징 (LIMIT)
출력되는 행의 수를 제한하며, 대량의 데이터를 페이지 단위로 끊어서 보여줄 때 필수적입니다. 인덱스는 0부터 시작합니다.
-- 상위 5개 데이터 추출
SELECT * FROM logs LIMIT 5;
-- 11번째부터 10개 추출 (Page 2 역할)
SELECT * FROM logs LIMIT 10 OFFSET 10;
-- 페이징 공식: LIMIT {size} OFFSET {(page - 1) * size}
6. SQL 실행 엔진의 논리적 순서
쿼리가 작성된 순서와 실제 실행되는 순서는 다릅니다. 이를 이해하면 쿼리 최적화와 에러 디버깅이 쉬워집니다.
- FROM: 대상 테이블 로드
- WHERE: 행 필터링
- SELECT: 컬럼 선택 및 계산, 별칭 부여
- ORDER BY: 데이터 정렬
- LIMIT: 최종 결과 행 수 제한