SQL은 데이터와 소통하기 위한 필수 언어입니다. 하지만 단순히 문법 암기를 넘어, 데이터베이스가 우리의 명령어를 어떤 순서로 생각하고 처리하는지 이해하고, 복잡한 질문을 던지기 전에 체계적으로 계획하는 습관을 들일 때 비로소 데이터의 잠재력을 온전히 끌어낼 수 있습니다.
이 가이드는 작은 온라인 서점을 운영하는 당신이 데이터 분석 전문가로 성장하는 여정을 안내합니다. 가장 단순한 질문에서 출발해 복잡한 비즈니스 인사이트를 얻기까지, SQL의 핵심 원리와 전문가의 작업 방식을 하나의 이야기처럼 엮어 설명합니다.
1단계: SQL의 첫걸음 - 원하는 데이터 꺼내보기
모든 분석은 "이 데이터가 궁금하다"는 질문에서 시작합니다. SQL의 SELECT, FROM, WHERE는 이 질문을 데이터베이스에 전달하는 가장 기본적인 도구입니다. 놀랍게도, 우리가 코드를 쓰는 순서와 데이터베이스가 일하는 순서는 다릅니다. 이 차이를 이해하는 것이 모든 것의 시작입니다.
- ✍️ 우리가 쓰는 순서: SELECT → FROM → WHERE
- ⚙️ 컴퓨터가 일하는 순서: FROM → WHERE → SELECT
컴퓨터의 논리적 순서에 따라 데이터가 어떻게 처리되는지 서점의 orders (주문 내역) 테이블을 예로 들어보겠습니다.
1. FROM: 어떤 장부를 펼칠까?
컴퓨터의 첫 번째 작업은 어떤 데이터 뭉치를 살펴볼지 결정하는 것입니다. FROM은 수많은 데이터 장부 중에서 orders라는 이름의 장부를 펼치라고 지시하는 것과 같습니다. 아직 특정 내용을 찾기 전, 정보가 담긴 큰 테이블 자체를 작업대로 가져오는 단계입니다.
FROM orders
2. WHERE: 어떤 내용을 찾아볼까?
장부를 펼쳤다면, 이제 우리가 원하는 **특정 조건의 데이터 행(row)**만 골라낼 차례입니다. WHERE는 수많은 주문 기록 중에서 '배송 준비 중' 상태인 주문들만 남겨달라고 요청하는 필터 역할을 합니다. 이때 다양한 비교 연산자를 활용할 수 있습니다.
- =: status = '배송 준비 중' (정확히 일치하는 값)
- >: price > 20000 (20,000원 초과)
- BETWEEN: order_date BETWEEN '2025-10-01' AND '2025-10-31' (특정 기간 사이)
- IN: user_id IN (101, 105, 203) (목록에 포함된 값)
- LIKE: book_title LIKE '%데이터%' ('데이터'라는 단어를 포함하는 값)
- IS NULL: payment_date IS NULL (아직 값이 없는, 즉 미결제 상태)
-- `orders` 장부를 펼쳐서 (`FROM`)
-- `status`가 'completed'인 주문들만 골라낸다 (`WHERE`)
WHERE status = 'completed'
3. SELECT: 어떤 항목을 보여줄까?
원하는 조건의 주문 기록들을 모두 찾았습니다. 마지막으로, 이 기록들에서 어떤 정보(column)를 최종적으로 확인하고 싶은지 결정합니다. SELECT는 '주문 번호'와 '주문 일자'만 뽑아서 보여달라고 요청하는 단계입니다. 모든 정보를 보고 싶을 때 *를 사용하지만, 이는 비효율을 낳을 수 있어 필요한 열만 명시하는 것이 좋습니다.
-- `orders` 장부에서 (`FROM`)
-- `status`가 'completed'인 주문들만 골라내어 (`WHERE`)
-- 최종적으로 `order_id`와 `order_date` 항목만 보여준다 (`SELECT`)
SELECT order_id, order_date
이 FROM → WHERE → SELECT의 세 박자 흐름은 모든 SQL 쿼리의 심장과도 같습니다.
2단계: 쿼리 확장하기 - 데이터 엮고, 묶고, 거르기
이제 우리는 더 복잡한 질문에 답해야 합니다. "어떤 책 카테고리가 가장 인기가 많을까?" 이 질문에 답하려면 여러 테이블의 정보를 합치고(JOIN), 데이터를 그룹화(GROUP BY)해야 합니다. SQL의 전체 실행 순서를 이해하면 이 과정이 명확해집니다.
SQL의 전체 논리적 실행 순서
- FROM / JOIN: 분석에 필요한 모든 테이블을 연결해 거대한 하나의 가상 테이블을 만듭니다. orders 테이블과 books 테이블을 book_id라는 공통 열쇠로 연결합니다.
- INNER JOIN: 두 테이블 모두에 book_id가 존재하는 주문만 남깁니다. (가장 흔하게 사용)
- LEFT JOIN: orders 테이블의 모든 주문을 일단 포함하고, books 테이블에 정보가 없는 책이라도 결과에 표시합니다. (예: 책 정보가 삭제되었지만 주문 기록은 남은 경우)
- WHERE: 연결된 가상 테이블의 개별 행을 대상으로 첫 번째 필터링을 합니다. 예를 들어, '반품' 상태의 주문은 분석에서 제외합니다. 이 단계는 데이터를 그룹으로 묶기 전이라, SUM() 같은 집계 함수는 쓸 수 없습니다.
- GROUP BY: WHERE 필터링을 통과한 데이터들을 특정 열(예: books.category) 기준으로 같은 것끼리 묶어 그룹을 형성합니다. '소설', '경제', 'IT' 등 각 카테고리별로 주문 더미를 쌓는 것과 같습니다.
- HAVING: GROUP BY로 만들어진 그룹 더미 자체를 대상으로 두 번째 필터링을 합니다. 이것이 WHERE와의 결정적 차이입니다. HAVING 절에서는 COUNT(order_id) > 10 (주문이 10건 이상인 카테고리만) 처럼 집계 함수의 결과를 조건으로 사용할 수 있습니다.
- SELECT: 살아남은 그룹들로부터 최종적으로 보고 싶은 정보를 계산하고 선택합니다. 각 그룹별로 category 이름, SUM(price) (카테고리 총매출), COUNT(*) (카테고리 판매량) 등을 계산합니다.
- ORDER BY: SELECT된 최종 결과 목록을 원하는 순서로 정렬합니다. ORDER BY total_revenue DESC는 총매출이 높은 순서(내림차순)로 정렬하라는 의미입니다.
- LIMIT: 정렬된 결과 중에서 상위 N개의 행만 보여줍니다. LIMIT 5는 가장 인기 있는 상위 5개 카테고리만 남깁니다.
3단계: 프로의 쿼리 작성법 - 코딩보다 설계 먼저
복잡한 분석일수록 바로 코딩을 시작하면 길을 잃기 쉽습니다. 전문가는 코드를 작성하기 전에 주석으로 '쿼리 설계도'를 먼저 그립니다. 이 간단한 습관이 실수를 막고, 분석의 정확성을 보장하며, 동료와의 협업을 극적으로 개선합니다.
실수를 방지하는 쿼리 템플릿
위 2단계의 질문 "어떤 책 카테고리가 가장 인기가 많을까?"를 분석하기 위해 아래와 같이 설계도를 먼저 작성해 봅시다.
-- ------------------------------------------------------------------
-- 🎯 목표: 2025년 3분기, 카테고리별 총매출과 판매량을 확인하여 인기 카테고리 Top 5를 도출한다.
-- 🔢 계산:
-- - 총매출 = SUM(o.price)
-- - 판매량 = COUNT(DISTINCT o.order_id)
-- 🗓️ 기간: 주문일자(o.order_date) 기준 '2025-07-01' ~ '2025-09-30'
-- 📚 테이블:
-- - orders (o): 주문 정보
-- - books (b): 도서 정보 (카테고리 포함)
-- 🔗 Join: orders.book_id = books.id (INNER JOIN)
-- ⚠️ 주의사항:
-- - '반품'(status = 'returned') 상태의 주문은 분석에서 제외.
-- - 판매량이 10건 미만인 카테고리는 통계적 의미가 적으므로 결과에서 제외.
-- ------------------------------------------------------------------
SELECT
b.category,
SUM(o.price) AS total_revenue,
COUNT(DISTINCT o.order_id) AS sales_count
FROM
orders AS o
INNER JOIN
books AS b ON o.book_id = b.id
WHERE
o.order_date BETWEEN '2025-07-01' AND '2025-09-30'
AND o.status != 'returned'
GROUP BY
b.category
HAVING
COUNT(DISTINCT o.order_id) >= 10
ORDER BY
total_revenue DESC
LIMIT 5;
이처럼 설계도를 먼저 작성하면, 위에서 배운 SQL의 실행 순서에 맞춰 각 절에 어떤 코드가 들어가야 할지 명확해집니다. 잘 짜인 계획은 복잡한 쿼리 작성을 마치 퍼즐 조각을 맞추는 것처럼 논리적이고 간단한 작업으로 만들어 줍니다.
결론: 체계적인 접근이 실력이다
진정한 SQL 실력은 단순히 많은 문법을 아는 것이 아니라, 명확한 목표를 가지고 데이터 처리 순서를 이해하며, 체계적인 계획하에 코드를 작성하는 능력입니다. 이 가이드에서 제시한 세 가지 단계—기초 이해, 실행 순서 파악, 사전 설계—를 꾸준히 연습한다면, 당신의 서점 데이터를 넘어 어떤 데이터 앞에서도 자신감 있는 전문가로 성장할 수 있을 것입니다.
관련 웹사이트 (URL)
- W3Schools SQL Tutorial: SQL의 기초부터 고급 기능까지 모든 것을 연습할 수 있는 최고의 학습 사이트입니다. https://www.w3schools.com/sql/
- SQL Style Guide: 여러 사람이 함께 작업하거나 장기적으로 코드를 관리할 때 유용한 SQL 코드 스타일 가이드입니다. https://www.sqlstyle.guide/
주요 용어 정리
- JOIN: 두 개 이상의 테이블을 공통된 열을 기준으로 연결하여 하나의 거대한 가상 테이블을 만드는 강력한 연산입니다.
- 집계 함수 (Aggregation Function): 여러 행의 값을 바탕으로 하나의 요약된 값(합계, 평균, 개수 등)을 계산하는 함수입니다. SUM(), AVG(), COUNT()가 대표적입니다.
- GROUP BY: 데이터를 특정 기준으로 그룹화하여, 각 그룹에 대해 집계 함수를 적용할 수 있게 하는 필수적인 절입니다.
- HAVING: GROUP BY로 생성된 그룹 자체를 필터링하는 절로, 집계 함수 결과를 조건으로 사용할 수 있습니다.
- 의사코드 (Pseudocode): 실제 코드 문법이 아닌, 사람의 언어로 논리의 흐름을 표현하는 방식. 쿼리 템플릿이 좋은 예시입니다.
'IT 지식 및 정보 (구글 클라우드 등)' 카테고리의 다른 글
| Google Cloud IAM (Identity and Access Management) 설명 (0) | 2025.11.27 |
|---|---|
| Google Cloud 네트워크 및 네트워크 보안 (0) | 2025.11.27 |
| SQL 데이터 조회의 3가지 핵심: FROM, WHERE, SELECT 완벽 가이드 (2) | 2025.10.22 |
| 데이터 분석의 첫걸음, 핵심 용어 완벽 정리 (0) | 2025.10.22 |
| Looker 생태계 마스터하기: 성공적인 BI 전략을 위한 데이터 설계, 비용 절감, 그리고 시각화 (0) | 2025.10.21 |