C
Database/SQL_기초/Lesson 03

SQL 실습 — 테이블 만들고 데이터 넣고 조회까지

1시간·theory
이 챕터
2/2

SQL 실습 — 테이블 만들고 데이터 넣고 조회까지

🎯 이 lesson 을 읽고 나면

이 lesson 을 다 읽고 나면 아래 3가지를 자신 있게 할 수 있습니다.

  • ✅ CREATE TABLE + FK + 제약조건으로 실제 스키마 작성
  • ✅ INSERT · UPDATE · DELETE 의 WHERE 누락 함정
  • ✅ 서브쿼리 IN vs EXISTS + GROUP BY + HAVING 조합

학습 목표를 체크리스트로 두고 다 답할 수 있게 되면 lesson 을 닫으세요.

테이블 만들기 — CREATE TABLE + 제약조건

DDL 의 시작

sql
CREATE TABLE users (
    id          BIGINT       AUTO_INCREMENT,
    email       VARCHAR(255) NOT NULL UNIQUE,
    name        VARCHAR(50)  NOT NULL,
    age         INT          CHECK (age >= 0),
    created_at  DATETIME     DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id)
);

제약조건 5가지

  • PRIMARY KEY유일 + NOT NULL. 행 식별자. 테이블에 1개만.
  • NOT NULL비어있을 수 없음.
  • UNIQUE중복 불가. PK 와 달리 여러 개 가능.
  • CHECK값의 범위 검증. CHECK (age >= 0).
  • FOREIGN KEY다른 테이블 참조. 무결성 보장.

외래키 — 관계 만들기

sql
CREATE TABLE orders (
    id       BIGINT AUTO_INCREMENT PRIMARY KEY,
    user_id  BIGINT NOT NULL,
    amount   INT,
    FOREIGN KEY (user_id) REFERENCES users(id)
        ON DELETE CASCADE
        ON UPDATE CASCADE
);

ON DELETE CASCADE — 부모 행 삭제 시 자식 행도 자동 삭제. RESTRICT (기본) 면 자식이 있으면 부모 삭제 거부.

INSERT · UPDATE · DELETE

sql
-- 추가
INSERT INTO users (email, name, age) VALUES ('[email protected]', 'Alice', 30);

-- 여러 행 한 번에
INSERT INTO users (email, name, age) VALUES
    ('[email protected]', 'Bob', 25),
    ('[email protected]', 'Carol', 28);

-- 수정
UPDATE users SET age = 31 WHERE email = '[email protected]';

-- 삭제
DELETE FROM users WHERE age < 20;

WHERE 없는 UPDATE/DELETE 는 전체 행이 대상. 실수로 한 줄 빼먹으면 테이블 통째로 사라집니다. 트랜잭션 안에서 시험하세요.

JOIN — INNER vs LEFT 의 차이

테스트 데이터

sql
users           orders
+----+-------+  +----+---------+--------+
| id | name  |  | id | user_id | amount |
+----+-------+  +----+---------+--------+
|  1 | A     |  |  1 |       1 |  10000 |
|  2 | B     |  |  2 |       1 |   5000 |
|  3 | C     |  |  3 |       3 |   8000 |
+----+-------+  +----+---------+--------+

INNER JOIN — 양쪽에 모두 있는 행만

sql
SELECT u.name, o.amount
FROM users u
INNER JOIN orders o ON u.id = o.user_id;

-- 결과: A/10000, A/5000, C/8000 (B 는 주문 없어서 제외)

LEFT JOIN — 왼쪽 테이블은 다 나옴

sql
SELECT u.name, o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;

-- 결과: A/10000, A/5000, B/NULL, C/8000

B 처럼 짝이 없는 사용자도 NULL 로 포함. "주문 없는 사용자 찾기" 에 자주:

sql
SELECT u.name FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE o.id IS NULL;
-- 결과: B

RIGHT JOIN — 거의 안 씀

테이블 순서 바꾸면 LEFT JOIN 으로 표현 가능. 통일성 위해 LEFT 만 쓰는 팀이 많습니다.

CROSS JOIN — 모든 조합

sql
SELECT a.name, b.name FROM users a CROSS JOIN users b;
-- 9행 (3 × 3)

카르테시안 곱. 실무에선 거의 사용 X — 실수로 ON 빼먹으면 발생하는 재앙.

서브쿼리 · GROUP BY · HAVING

서브쿼리 3종

IN — 목록 안에 있나

sql
SELECT name FROM users
WHERE id IN (SELECT user_id FROM orders WHERE amount > 5000);

EXISTS — 한 행이라도 있나 (성능 우수)

sql
SELECT name FROM users u
WHERE EXISTS (
    SELECT 1 FROM orders o WHERE o.user_id = u.id AND o.amount > 5000
);

EXISTS 는 첫 행을 만나는 순간 종료 → 큰 테이블에서 IN 보다 빠를 때 많음.

스칼라 서브쿼리 — 한 값 만 리턴

sql
SELECT name,
       (SELECT COUNT(*) FROM orders o WHERE o.user_id = u.id) AS order_count
FROM users u;

SELECT 절에 각 행마다 1번씩 실행 — 작은 테이블 외엔 JOIN 으로 바꾸는 게 빠릅니다.

GROUP BY — 집계 함수의 짝

sql
-- 사용자별 총 주문액
SELECT user_id, SUM(amount) AS total
FROM orders
GROUP BY user_id;

GROUP BY 컬럼이 아닌 컬럼 을 SELECT 에 쓰면 에러 (또는 비표준 동작). 집계 함수 5개:

  • COUNT(*) — 행 수
  • SUM(col) — 합계
  • AVG(col) — 평균
  • MAX(col) / MIN(col) — 최대/최소

HAVING vs WHERE

WHERE 는 그룹 만들기 전 필터, HAVING 은 그룹 만든 뒤 필터.

sql
SELECT user_id, SUM(amount) AS total
FROM orders
WHERE amount > 1000               -- 1000 초과 주문만
GROUP BY user_id
HAVING SUM(amount) > 10000;       -- 합계가 1만 초과인 사용자만

HAVING 에 집계 함수를 쓸 수 있는 게 차이의 핵심. WHERE 에는 SUM() 못 씁니다.

ORDER BY · LIMIT

sql
SELECT name FROM users
ORDER BY created_at DESC
LIMIT 10 OFFSET 20;

3페이지 데이터 (페이지당 10개) 를 가져옴. 페이지네이션의 기본 패턴.

실전 합치기 — 상위 사용자 TOP 5

sql
SELECT u.name, SUM(o.amount) AS total
FROM users u
JOIN orders o ON u.id = o.user_id
GROUP BY u.id, u.name
HAVING SUM(o.amount) > 0
ORDER BY total DESC
LIMIT 5;

JOIN + GROUP BY + HAVING + ORDER BY + LIMIT — 실무 쿼리의 90% 가 이 조합입니다.

🤖 AI 에게 이렇게 요청해보세요

이 lesson 의 개념을 알면 AI 에게 구체적으로 지시할 수 있습니다. 막연한 "고쳐줘" 가 아니라 어휘를 가진 요청 — 그게 토큰 절약의 출발점입니다.

  • "users · orders · products 3 테이블 설계 + FK + INDEX 까지 만들어줘"
  • "최근 7일 가입한 사용자 수를 일별로 집계하는 쿼리 작성해줘"
  • "이 쿼리에 EXPLAIN 붙여서 실행계획 해석해줘"

왜 이게 토큰을 줄이나

개념을 모를 땐 AI 답변을 받고도 "그게 뭐예요?" 를 다시 물어야 합니다. 그 "다시 물음" 이 토큰을 잡아먹습니다. 개념 한 번 익혀두면 대화가 한 번에 끝납니다.

SQL 실습 — 테이블 만들고 데이터 넣고 조회까지 - Database