원칙 1,2 — SELECT + FROM
원칙 1,2 — SELECT + FROM
어떤 열을, 어느 테이블에서 가져올까?
박지수 팀장 : 민서씨, 첫 번째 미션이에요. 고객 테이블에서 이름이랑 등급만 뽑아볼 수 있어요? 전체 열이 너무 많아서 보고서에 넣기 어렵거든요.
김민서 사원 : 네! 그런데... 테이블이 어떻게 생겼는지부터 확인해봐야 할 것 같아요.
좋은 시작입니다.
SQL을 쓸 때 가장 먼저 하는 생각이 바로 이겁니다. "나는 어떤 열을, 어느 테이블에서 꺼내고 싶은가?" 이 두 질문에 답하는 것이 SELECT와 FROM입니다.
이런 결과를 원할 때
전체 열을 한눈에 보고 싶다:
| 고객ID | 이름 | 나이 | 지역 | 등급 | 이메일 | 가입일 |
|---|---|---|---|---|---|---|
| 1 | 김민수 | 28 | 서울 | VIP | minsu@mail.com | 2023-03-15 |
| 2 | 이지은 | 35 | 부산 | 일반 | NULL | 2023-05-22 |
| 3 | 박서연 | NULL | 서울 | VIP | sy.park@mail.com | 2023-07-01 |
원하는 열만 뽑고 싶다:
| 이름 | 등급 |
|---|---|
| 김민수 | VIP |
| 이지은 | 일반 |
| 박서연 | VIP |
이 두 가지를 만드는 것이 이번 챕터의 목표입니다.
SELECT + FROM이 하는 일
SELECT 열이름1, 열이름2
FROM 테이블이름;
두 줄을 나란히 읽으면 이렇게 됩니다.
SELECT 이름, 등급← "이름과 등급 열을"FROM 고객정보← "고객정보 테이블에서 가져와라"
FROM이 먼저입니다. 어느 테이블에서 꺼낼지 정합니다.
SELECT가 그 다음입니다. 그 테이블에서 어떤 열을 볼지 고릅니다.
코드를 쓰는 순서는 SELECT → FROM이지만,
머릿속으로 생각하는 순서는 FROM → SELECT입니다.
💡 결과를 먼저 그리는 습관
SQL을 잘 쓰는 사람들은 코드를 쓰기 전에 항상 이 두 가지를 먼저 생각합니다. "어느 테이블이지?" → "거기서 어떤 열이 필요하지?"
이 순서로 생각하면 코드가 자연스럽게 나옵니다.
STEP 1 — 테이블 전체를 먼저 살펴보자
처음 보는 테이블은 전체 구조를 먼저 확인합니다. *는 "모든 열"을 뜻합니다.
SELECT *
FROM 고객정보;
실행 결과:
| 고객ID | 이름 | 나이 | 지역 | 등급 | 이메일 | 가입일 |
|---|---|---|---|---|---|---|
| 1 | 김민수 | 28 | 서울 | VIP | minsu@mail.com | 2023-03-15 |
| 2 | 이지은 | 35 | 부산 | 일반 | NULL | 2023-05-22 |
| 3 | 박서연 | NULL | 서울 | VIP | sy.park@mail.com | 2023-07-01 |
| 4 | 최준호 | 41 | 대구 | NULL | junho@mail.com | 2023-01-10 |
| 5 | 정하윤 | 29 | 서울 | 프리미엄 | NULL | 2024-02-14 |
| 6 | 강도윤 | 33 | NULL | VIP | doyun@company.co.kr | 2023-11-30 |
| 7 | 윤서준 | 27 | 대구 | 일반 | sjyoon@mail.com | NULL |
| 8 | 임수아 | NULL | 서울 | 프리미엄 | sua_lim@mail.com | 2024-01-05 |
| 9 | 한예진 | 45 | 부산 | NULL | NULL | 2022-08-20 |
| 10 | 오태양 | 31 | NULL | 일반 | taeyang5@mail.com | 2024-03-01 |
열이 7개, 행이 10개. 어떤 열이 있는지, 어떤 값이 들어있는지 한눈에 보입니다. 다른 테이블도 마찬가지로 확인해봅니다.
SELECT *
FROM 판매정보;
실행 결과:
| 판매ID | 고객ID | 상품명 | 카테고리 | 수량 | 단가 | 할인율 | 판매일 |
|---|---|---|---|---|---|---|---|
| 1 | 1 | 노트북 Pro | 전자기기 | 1 | 1,500,000 | 0.1 | 2024-01-15 |
| 2 | 2 | 무선 키보드 | 주변기기 | 2 | 45,000 | NULL | 2024-01-20 |
| 3 | 1 | 마우스 패드 | 주변기기 | 3 | 15,000 | 0 | 2024-02-01 |
| 4 | 3 | 모니터 27인치 | 전자기기 | 1 | 350,000 | 0.15 | 2024-02-10 |
| 5 | 4 | USB 허브 | 주변기기 | 1 | 25,000 | NULL | NULL |
| 6 | 5 | 노트북 Air | 전자기기 | 2 | 1,200,000 | 0.05 | 2024-03-01 |
| 7 | NULL | 마우스 패드 | 주변기기 | 5 | 15,000 | 0.2 | 2024-03-05 |
| 8 | 6 | 모니터 32인치 | 전자기기 | 1 | 550,000 | NULL | 2024-03-10 |
| 9 | 2 | 노트북 Pro | 전자기기 | 1 | 1,500,000 | 0.1 | 2024-03-15 |
| 10 | 7 | 무선 키보드 | 주변기기 | NULL | 45,000 | 0 | 2024-03-20 |
| 11 | 9 | 웹캠 HD | NULL | 1 | 89,000 | 0.1 | 2024-04-01 |
| 12 | NULL | 노트북 Air | 전자기기 | 1 | 1,200,000 | NULL | 2024-04-10 |
이제 두 테이블의 구조가 눈에 익었습니다.
💡 테이블을 탐색하는 실무 루틴
새로운 테이블을 받았을 때 가장 먼저 하는 것입니다.
-- 실제 데이터 확인 (5행만)
SELECT * FROM 테이블이름 LIMIT 5;
LIMIT 5는 위에서 5행만 보여줍니다. 데이터가 수천 건이어도 구조만 빠르게 확인할 수 있습니다.
STEP 2 — 원하는 열만 고르자
구조를 파악했으니 팀장이 요청한 열만 꺼냅니다.
SELECT 이름, 등급
FROM 고객정보;
실행 결과:
| 이름 | 등급 |
|---|---|
| 김민수 | VIP |
| 이지은 | 일반 |
| 박서연 | VIP |
| 최준호 | NULL |
| 정하윤 | 프리미엄 |
| 강도윤 | VIP |
| 윤서준 | 일반 |
| 임수아 | 프리미엄 |
| 한예진 | NULL |
| 오태양 | 일반 |
열 7개 가운데 2개만 남았습니다.
열 이름은 쉼표로 나열합니다.
-- 이름이 먼저 나옴
SELECT 이름, 등급
FROM 고객정보;
-- 등급이 먼저 나옴
SELECT 등급, 이름
FROM 고객정보;
판매정보 테이블도 마찬가지입니다.
SELECT 상품명, 단가
FROM 판매정보;
실행 결과:
| 상품명 | 단가 |
|---|---|
| 노트북 Pro | 1,500,000 |
| 무선 키보드 | 45,000 |
| 마우스 패드 | 15,000 |
| 모니터 27인치 | 350,000 |
| USB 허브 | 25,000 |
| 노트북 Air | 1,200,000 |
| 마우스 패드 | 15,000 |
| 모니터 32인치 | 550,000 |
| 노트북 Pro | 1,500,000 |
| 무선 키보드 | 45,000 |
| 웹캠 HD | 89,000 |
| 노트북 Air | 1,200,000 |
STEP 3 — 열 이름을 바꿔서 보여주자
결과에 보이는 열 이름을 바꾸고 싶을 때는 AS를 씁니다. 데이터는 그대로이고 이름만 바뀝니다.
SELECT 이름 AS 고객명,
등급 AS 멤버십등급,
지역 AS 거주지역
FROM 고객정보;
실행 결과:
| 고객명 | 멤버십등급 | 거주지역 |
|---|---|---|
| 김민수 | VIP | 서울 |
| 이지은 | 일반 | 부산 |
| 박서연 | VIP | 서울 |
| 최준호 | NULL | 대구 |
| 정하윤 | 프리미엄 | 서울 |
| 강도윤 | VIP | NULL |
| 윤서준 | 일반 | 대구 |
| 임수아 | 프리미엄 | 서울 |
| 한예진 | NULL | 부산 |
| 오태양 | 일반 | NULL |
보고서에 바로 넣을 수 있는 형태가 됩니다.
💡 AS는 생략할 수 있습니다.
SELECT 이름 고객명
FROM 고객정보;
하지만 AS를 명시하는 것이 코드를 읽기 훨씬 쉽습니다.
STEP 4 — 없는 열도 만들어서 보여주자
SELECT에는 열 이름뿐만 아니라 계산식도 쓸 수 있습니다. 테이블에 없는 값을 즉석에서 만들어 새 열처럼 출력합니다.
SELECT 상품명,
단가,
단가 * 0.9 AS 할인가
FROM 판매정보
LIMIT 5;
실행 결과 (첫 5행):
| 상품명 | 단가 | 할인가 |
|---|---|---|
| 노트북 Pro | 1,500,000 | 1,350,000 |
| 무선 키보드 | 45,000 | 40,500 |
| 마우스 패드 | 15,000 | 13,500 |
| 모니터 27인치 | 350,000 | 315,000 |
| USB 허브 | 25,000 | 22,500 |
할인가는 테이블에 없는 열입니다.
단가 * 0.9로 즉석에서 계산해서 새 열처럼 만들었습니다.
사칙연산은 +, -, *, /를 모두 쓸 수 있습니다.
STEP 5 — 중복을 제거하고 보자
판매정보에 어떤 상품이 있는지 확인하고 싶습니다. 그냥 조회하면 같은 상품이 여러 번 반복됩니다.
SELECT 상품명
FROM 판매정보;
실행 결과:
| 상품명 |
|---|
| 노트북 Pro |
| 무선 키보드 |
| 마우스 패드 |
| 모니터 27인치 |
| USB 허브 |
| 노트북 Air |
| 마우스 패드 |
| 모니터 32인치 |
| 노트북 Pro |
| 무선 키보드 |
| 웹캠 HD |
| 노트북 Air |
같은 상품명이 반복됩니다.
DISTINCT를 쓰면 고유한 값만 남습니다.
SELECT DISTINCT 상품명
FROM 판매정보;
실행 결과:
| 상품명 |
|---|
| 노트북 Pro |
| 무선 키보드 |
| 마우스 패드 |
| 모니터 27인치 |
| USB 허브 |
| 노트북 Air |
| 모니터 32인치 |
| 웹캠 HD |
12행에서 8행으로 줄었습니다. 이 테이블에 상품명이 여덟 종류라는 것을 바로 알 수 있습니다.
고객정보 테이블에서 지역 종류를 확인하는 것도 같은 방식입니다.
SELECT DISTINCT 지역
FROM 고객정보;
실행 결과:
| 지역 |
|---|
| 서울 |
| 부산 |
| 대구 |
| NULL |