데이터 조작의 기본인 CRUD(Create, Read, Update, Delete) 명령어를 정리합니다.

샘플 테이블 준비

CREATE TABLE employees (
    id         INT NOT NULL AUTO_INCREMENT,
    name       VARCHAR(50) NOT NULL,
    dept       VARCHAR(30),
    salary     DECIMAL(10,2) DEFAULT 0,
    hire_date  DATE,
    PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT (데이터 삽입)

기본 삽입

-- 전체 컬럼 지정
INSERT INTO employees (name, dept, salary, hire_date)
VALUES ('홍길동', '개발팀', 5000000, '2024-01-15');

-- 여러 행 한번에 삽입
INSERT INTO employees (name, dept, salary, hire_date) VALUES
('김철수', '기획팀', 4500000, '2024-02-01'),
('이영희', '개발팀', 5500000, '2023-06-10'),
('박민수', '디자인팀', 4800000, '2024-03-20'),
('최지은', '개발팀', 6000000, '2022-11-05');

INSERT 변형

-- 중복 키 발생 시 무시
INSERT IGNORE INTO employees (id, name, dept) VALUES (1, '홍길동', '인사팀');

-- 중복 키 발생 시 UPDATE 실행
INSERT INTO employees (id, name, dept, salary)
VALUES (1, '홍길동', '인사팀', 5500000)
ON DUPLICATE KEY UPDATE dept = VALUES(dept), salary = VALUES(salary);

-- 다른 테이블에서 복사
INSERT INTO employees_backup
SELECT * FROM employees WHERE dept = '개발팀';

-- REPLACE: 중복 시 DELETE 후 INSERT
REPLACE INTO employees (id, name, dept, salary)
VALUES (1, '홍길동', '인사팀', 5500000);

SELECT (데이터 조회)

기본 조회

-- 전체 조회
SELECT * FROM employees;

-- 특정 컬럼 조회
SELECT name, dept, salary FROM employees;

-- 별칭(Alias) 사용
SELECT name AS 이름, dept AS 부서, salary AS 급여 FROM employees;

-- 중복 제거
SELECT DISTINCT dept FROM employees;

WHERE 조건절

-- 비교 연산자
SELECT * FROM employees WHERE salary >= 5000000;
SELECT * FROM employees WHERE dept = '개발팀';
SELECT * FROM employees WHERE dept != '기획팀';

-- 논리 연산자
SELECT * FROM employees WHERE dept = '개발팀' AND salary >= 5000000;
SELECT * FROM employees WHERE dept = '개발팀' OR dept = '기획팀';
SELECT * FROM employees WHERE NOT dept = '디자인팀';

-- BETWEEN (범위)
SELECT * FROM employees WHERE salary BETWEEN 4500000 AND 5500000;

-- IN (목록)
SELECT * FROM employees WHERE dept IN ('개발팀', '기획팀');

-- LIKE (패턴 매칭)
SELECT * FROM employees WHERE name LIKE '김%';    -- '김'으로 시작
SELECT * FROM employees WHERE name LIKE '%수';    -- '수'로 끝남
SELECT * FROM employees WHERE name LIKE '%길%';   -- '길' 포함
SELECT * FROM employees WHERE name LIKE '홍__';   -- '홍' + 2글자

-- NULL 체크
SELECT * FROM employees WHERE dept IS NULL;
SELECT * FROM employees WHERE dept IS NOT NULL;

정렬 (ORDER BY)

-- 오름차순 (기본)
SELECT * FROM employees ORDER BY salary ASC;

-- 내림차순
SELECT * FROM employees ORDER BY salary DESC;

-- 다중 정렬
SELECT * FROM employees ORDER BY dept ASC, salary DESC;

제한 (LIMIT)

-- 상위 3건
SELECT * FROM employees ORDER BY salary DESC LIMIT 3;

-- 페이징: 2번째부터 3건 (OFFSET 시작은 0)
SELECT * FROM employees ORDER BY id LIMIT 3 OFFSET 2;
-- 동일한 표현
SELECT * FROM employees ORDER BY id LIMIT 2, 3;

UPDATE (데이터 수정)

-- 단일 컬럼 수정
UPDATE employees SET salary = 5200000 WHERE id = 1;

-- 다중 컬럼 수정
UPDATE employees SET dept = '인사팀', salary = 5300000 WHERE id = 1;

-- 조건부 수정
UPDATE employees SET salary = salary * 1.1 WHERE dept = '개발팀';

-- 전체 수정 (주의: WHERE 없으면 전체 행 수정)
UPDATE employees SET is_active = 1;

⚠️ UPDATE/DELETE 시 WHERE 절을 빠뜨리면 전체 데이터가 변경/삭제됩니다.
Safe Updates 모드를 활성화하면 실수를 방지할 수 있습니다.

SET SQL_SAFE_UPDATES = 1;

DELETE (데이터 삭제)

-- 조건부 삭제
DELETE FROM employees WHERE id = 5;

-- 여러 조건으로 삭제
DELETE FROM employees WHERE dept = '기획팀' AND salary < 4000000;

-- 전체 삭제 (주의)
DELETE FROM employees;

-- 전체 삭제 + AUTO_INCREMENT 리셋 (더 빠름)
TRUNCATE TABLE employees;

DELETE vs TRUNCATE

항목 DELETE TRUNCATE
WHERE 조건 사용 가능 사용 불가 (전체 삭제만)
속도 느림 (행 단위 삭제) 빠름 (테이블 재생성)
AUTO_INCREMENT 유지 리셋
트랜잭션 ROLLBACK 가능 ROLLBACK 불가
트리거 실행됨 실행 안됨

집계 함수

-- 건수
SELECT COUNT(*) FROM employees;
SELECT COUNT(DISTINCT dept) FROM employees;

-- 합계, 평균, 최대, 최소
SELECT SUM(salary) AS 총급여 FROM employees;
SELECT AVG(salary) AS 평균급여 FROM employees;
SELECT MAX(salary) AS 최고급여 FROM employees;
SELECT MIN(salary) AS 최저급여 FROM employees;

-- 부서별 집계
SELECT dept, COUNT(*) AS 인원, AVG(salary) AS 평균급여
FROM employees
GROUP BY dept;

-- HAVING: 그룹 조건
SELECT dept, AVG(salary) AS avg_sal
FROM employees
GROUP BY dept
HAVING avg_sal >= 5000000;

SELECT 실행 순서

FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT

이 순서를 이해하면 별칭(alias)을 WHERE에서 사용할 수 없는 이유 등을 알 수 있습니다.

관련된 글 (mysql > lecture-mysql)