GROUP BY로 채널별로 묶고, HAVING으로 조건을 걸어야 "진짜 분석"이 시작된다.
실행 순서를 모르면 오류가 나는 이유조차 모른다.
[TIL] Day5 | SQL로 채널 성과 분석하기
— GROUP BY, HAVING, 실행 순서까지
— GROUP BY, HAVING, 실행 순서까지
💡 오늘 한 줄 요약
1. SQL 기초 복습
SQL은 데이터베이스에서 조회·추가·수정·삭제를 담당하는 언어. 엑셀에서 필터/정렬/피벗을 코드로 하는 것이라고 이해하면 쉽다.
그로스 마케터가 SQL을 배워야 하는 이유
광고 채널별 전환율을 직접 뽑고, 특정 기간 매출을 즉시 확인할 수 있다. 개발팀에 의존하지 않아도 됨.
광고 채널별 전환율을 직접 뽑고, 특정 기간 매출을 즉시 확인할 수 있다. 개발팀에 의존하지 않아도 됨.
| 명령어 | 종류 | 역할 |
|---|---|---|
CREATE / DROP / ALTER |
DDL | 테이블 구조 관련 |
INSERT / SELECT / UPDATE / DELETE |
DML | 데이터 조작 관련 |
수업은 MySQL 기준. Oracle과 자동 증가(AUTO_INCREMENT vs SEQUENCE), 날짜 함수(NOW() vs SYSDATE), 상위 N개(LIMIT vs FETCH FIRST N ROWS ONLY) 등이 다르다는 것만 기억.
2. INSERT INTO — 데이터 넣기 핵심
실습은 음악 스트리밍 서비스 BeatWave의 3개 테이블(ad_campaigns, users, daily_revenue)을 사용.
컬럼명 지정 방식을 써라 (권장)
-- ✅ 권장: 컬럼명 지정 방식
INSERT INTO ad_campaigns (campaign_name, channel, budget)
VALUES ('봄 신상 캠페인', 'Instagram', 600000);
-- MySQL 전용: 여러 행 한 번에 INSERT (Oracle은 지원 안 함!)
INSERT INTO ad_campaigns (campaign_name, channel, budget)
VALUES
('봄 신상 캠페인', 'Instagram', 600000),
('여름 세일', 'Google Ads', 900000),
('블랙프라이데이', 'Facebook', 1200000);
CREATE TABLE 핵심 제약 조건
•
•
•
•
NOT NULL — 반드시 값을 넣어야 함•
DEFAULT 0 — 값을 안 넣으면 자동으로 기본값 세팅•
AUTO_INCREMENT — id를 내가 안 넣어도 자동으로 1, 2, 3... 증가 (MySQL 전용)3. ORDER BY + LIMIT — 정렬과 상위 N개
결과를 오름차순(ASC) 또는 내림차순(DESC)으로 정렬. 아무것도 안 쓰면 ASC가 기본.
-- 전환수 TOP 3 캠페인 찾기
SELECT campaign_name, channel, conversions
FROM ad_campaigns
ORDER BY conversions DESC
LIMIT 3;
-- 여러 기준 정렬: 채널 이름순 → 같은 채널이면 예산 높은 순
ORDER BY channel ASC, budget DESC;
MySQL vs Oracle 상위 N개 조회
MySQL:
MySQL:
LIMIT 3 | Oracle: FETCH FIRST 3 ROWS ONLY4. GROUP BY + 집계함수 ⭐⭐⭐
오늘의 핵심. GROUP BY는 같은 값을 가진 행들을 하나로 묶어서 합계·평균·개수 등을 계산한다. 엑셀의 피벗 테이블과 같은 역할.
집계 함수 한눈에
| 함수 | 설명 | 마케팅 활용 예 |
|---|---|---|
COUNT(*) |
행 개수 세기 | 채널별 캠페인 몇 개? |
SUM(컬럼) |
합계 | 채널별 총 예산은? |
AVG(컬럼) |
평균 | 평균 전환수? |
MAX(컬럼) |
최대값 | 가장 높은 전환 캠페인? |
MIN(컬럼) |
최소값 | 가장 낮은 예산 캠페인? |
ROUND(n, d) |
반올림 | CTR 소수점 2자리 |
채널별 성과 분석 예시
-- 채널별 총 예산·전환수·CTR 한 번에
SELECT
channel,
SUM(budget) AS total_budget,
SUM(conversions) AS total_conversions,
ROUND(SUM(clicks) / SUM(impressions) * 100, 2) AS ctr_pct
FROM ad_campaigns
GROUP BY channel
ORDER BY total_budget DESC;
⚠️ GROUP BY 자주 하는 실수
SELECT에 GROUP BY에 없는 일반 컬럼을 쓰면 오류!
집계함수가 아닌 컬럼은 반드시 GROUP BY에 포함시켜야 한다.
SELECT에 GROUP BY에 없는 일반 컬럼을 쓰면 오류!
집계함수가 아닌 컬럼은 반드시 GROUP BY에 포함시켜야 한다.
CASE WHEN — 조건부 집계 (엑셀 IF와 같다)
-- 지역별 사용자 수 + 그 중 premium 유저 수
SELECT
region,
COUNT(*) AS total_users,
SUM(CASE WHEN plan = 'premium' THEN 1 ELSE 0 END) AS premium_count
FROM users
GROUP BY region
ORDER BY total_users DESC;
CASE WHEN 조건 THEN 값 ELSE 다른값 ENDpremium이면 1, 아니면 0을 반환 → SUM으로 더하면 premium 유저 수가 나온다.
5. HAVING — 그룹 조건 필터링 ⭐⭐⭐
GROUP BY로 묶은 결과에 조건을 거는 명령어. WHERE와 가장 헷갈리는 부분이므로 정확히 구분해야 한다.
WHERE는 그룹 전, HAVING은 그룹 후 — 위치가 다르면 오류!
자주 하는 실수 — WHERE에서 집계 결과 쓰기
-- ❌ 오류 발생! WHERE에서는 집계 결과(SUM) 못 씀
SELECT channel, SUM(conversions) AS total_conversions
FROM ad_campaigns
WHERE total_conversions >= 3000 -- ❌ Unknown column 에러!
GROUP BY channel;
-- ✅ 올바른 방법: HAVING 사용
SELECT channel, SUM(conversions) AS total_conversions
FROM ad_campaigns
GROUP BY channel
HAVING SUM(conversions) >= 3000
ORDER BY total_conversions DESC;
WHERE + GROUP BY + HAVING 조합
-- 3~4월 캠페인 중, 총 예산 100만원 이상인 채널만
SELECT
channel,
COUNT(*) AS campaign_count,
SUM(budget) AS total_budget
FROM ad_campaigns
WHERE start_date BETWEEN '2024-03-01' AND '2024-04-30' -- 행 필터
GROUP BY channel
HAVING SUM(budget) >= 1000000 -- 그룹 필터
ORDER BY total_budget DESC;
6. SELECT 실행 순서 ⭐⭐⭐
SQL은 우리가 쓰는 순서대로 실행되지 않는다. 실제 실행 순서를 모르면 오류 원인을 파악할 수 없다.
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
💡 이 순서가 중요한 이유
HAVING(4단계)이 SELECT(5단계)보다 먼저 실행된다.
→ 그래서
→ 별명이 아직 정의되지 않은 단계이기 때문.
HAVING(4단계)이 SELECT(5단계)보다 먼저 실행된다.
→ 그래서
HAVING total_conversions >= 3000 처럼 AS 별명을 HAVING에서 쓰면 오류!→ 별명이 아직 정의되지 않은 단계이기 때문.
HAVING SUM(conversions) >= 3000 으로 써야 한다.| 단계 | 절 | 하는 일 |
|---|---|---|
| 1 | FROM |
어느 테이블에서 데이터를 가져올지 |
| 2 | WHERE |
개별 행 중 조건에 맞는 행만 추리기 |
| 3 | GROUP BY |
지정 컬럼 기준으로 행 묶기 |
| 4 | HAVING |
묶인 그룹 중 조건에 맞는 그룹만 남기기 |
| 5 | SELECT |
조회할 컬럼 및 집계값 계산 |
| 6 | ORDER BY |
결과 정렬 |
| 7 | LIMIT |
상위 N개만 출력 |
7. 마케팅 지표 SQL 공식 모음 ⭐⭐⭐
그로스 마케터가 실전에서 바로 쓸 수 있는 SQL 공식. 외워두면 분석 속도가 확 달라진다.
CTR / CVR / CPC / CPA / ROI — 5가지 공식 치트시트
채널별 ROI 종합 분석 쿼리 (최종 실습 핵심)
-- 채널별 ROI 분석 (객단가 9,900원 가정)
SELECT
channel,
SUM(budget) AS total_budget,
SUM(conversions) AS total_conversions,
SUM(conversions) * 9900 AS estimated_revenue,
ROUND((SUM(conversions) * 9900 - SUM(budget)) / SUM(budget) * 100, 1) AS roi_pct,
ROUND(SUM(budget) / SUM(conversions), 0) AS cpa
FROM ad_campaigns
GROUP BY channel
HAVING SUM(conversions) >= 1500 -- 총 전환수 1,500 이상
AND AVG(clicks / impressions * 100) >= 6.0 -- CTR 6% 이상
ORDER BY roi_pct DESC;
ROI 해석 기준
ROI > 100% → 광고비보다 벌어들인 금액이 더 크다 = 흑자 캠페인 ✅
ROI < 100% → 광고비가 매출보다 크다 = 손해 중 ❌
ROI > 100% → 광고비보다 벌어들인 금액이 더 크다 = 흑자 캠페인 ✅
ROI < 100% → 광고비가 매출보다 크다 = 손해 중 ❌
📌 오늘의 핵심 정리
- GROUP BY는 엑셀 피벗 테이블 = 같은 값끼리 묶어서 집계 (SUM, COUNT, AVG...)
- HAVING은 GROUP BY 이후에 조건 → 집계 결과에 조건 걸 때 WHERE 대신 사용
- WHERE vs HAVING — WHERE는 그룹 전 / HAVING은 그룹 후, 헷갈리면 오류!
- SELECT 실행 순서 → FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
- HAVING에서 AS 별명 못 쓰는 이유: SELECT보다 먼저 실행되기 때문
- 마케팅 지표 공식: CTR(클릭/노출) · CVR(전환/클릭) · CPC(예산/클릭) · CPA(예산/전환) · ROI((전환×객단가-예산)/예산)
- MySQL 전용 주의:
LIMIT,AUTO_INCREMENT,DATE_FORMAT(), 멀티 INSERT
'부트캠프' 카테고리의 다른 글
| 멋쟁이사자처럼 부트캠프 그로스마케팅 4기 23일차_260410 (0) | 2026.04.10 |
|---|---|
| 멋쟁이사자처럼 부트캠프 그로스마케팅 4기 22일차_260409 (0) | 2026.04.09 |
| 멋쟁이사자처럼 부트캠프 그로스마케팅 4기 20일차(2)_260407 (0) | 2026.04.07 |
| 멋쟁이사자처럼 부트캠프 그로스마케팅 4기 18일차_260402(다른버전) (0) | 2026.04.07 |
| 멋쟁이사자처럼 부트캠프 그로스마케팅 4기 20일차_260407 (1) | 2026.04.07 |