[데이터분석] SQL 실무 예제로 공부하기-기획자의 SQL 책 리뷰

2026. 1. 9. 16:00·데이터

SQLD 도 땄었고 SQL 문제도 자주 풀긴 했지만 실무 문제들은 풀 때마다 언제나 헷갈리는 것 같다.ㅠㅠ

또한 기획자들의 데이터분석은 또 그 요구조건이 다르기 때문에 고민하다가 이 책을 발견하게 되었다! 

좋은 내용이 많아서 리뷰하며 정리한다! 

 

기획자의 SQL | 조은성 - 교보문고

기획자의 SQL | 기획자에게 필요한 SQL은 따로 있다기획자는 데이터를 보는 관점이 개발자와 다르다. 기획자나 마케터, 일반 사무직에 이르기까지 많은 직장인이 데이터를 본다. 개발자와 달리 그

product.kyobobook.co.kr

 

0. SQL 의 종류 -까먹지 말기! 

구분 명령어 실행
DML
(Data Manipulation Language)
SELECT
INSERT
UPDATE
DELETE
-데이터베이스에서 데이터를 검색 (SELECT)
-테이블에서 새로운 행 삽입 (INSERT)
-기존의 행 수정(UPDATE)
-기존의 행 삭제(DELETE)
DDL
(Data Definition Language)
CREATE
DROP
TRUNCATE
-테이블의 데이터를 정의하고
-구조를 생성하거나
-구조를 수정 또는 제거
DCL 
(Data Control Language)
GRANT
REVOKE
-데이터베이스에 대해 접근 권한을 부여하거나 제거
TCL 
(Transaction Control Language)
COMMIT
ROLLBACK
SAVEPOINT
DML로 실행한 변경사항을 저장 관리

1. 컴퓨터에게 어떻게 명령어를 입력해야 할까?

SQL은 데이터를 가져올 때 사용하느 컴퓨터가 이해할 수 있는 언어이기 때문에 

컴퓨터가 이해하기 쉽도록 명령해야 나의 요구 조건을 이해하고 실행할 수 있다. 

우리가 무언가를 가져오도록 시킬 때

  • '무엇'을 가져와야 하는지
  • '어디에서' 가져와야 하는지

가 주요 포인트이다. 즉 데이터도 마찬가지다! 

 

데이터 가져다 줘 전부 다
저장소 위치가 어디냐면 여기야
명령 끝! 

 

요거를 SQL 명령어로 바꾸면

SELECT *
FROM [테이블명]
;

 

2. 조건 걸기 - WHERE

  • AND: 두 조건을 연결하며, 둘 다 참인 데이터를 조회한다.
  • BETWEEN: 시작 값과 종료 값을 포함하는 범위 내의 데이터 조회하며 시작 날짜와 종료 날짜를 포함한 값을 반환한다.
  • OR: 둘 중 하나라도 참이면 조건을 만족한다 / AND 와 OR 연산자 중 우선순위는 AND가 더 높다.
  • IN: 조건 값 중 하나라도 해당 컬럼의 값과 일치하면 해당 행의 데이터를 조회한다.
  • LIKE: 패턴 매칭 필터링을 가능하게 해준다. [컬럼명] LIKE [와일드카드] 형태로 작성한다. 
    • % 는 0개 이상의 임의의 문자열 패턴을 의미하는 메타 문자
    • _는 임의의 문자 한 개를 의미하는 메타 문자
    • []는 문자 집합을 의미하는 메타 문자 
    • NOT LIKE = 다음과 일치하지 않는
  • IS: null 값을 필터링할 때 사용 
    • ⭐️이 때, NOT을 추가할 때는 LIKE와 다르게 IS 뒤에 NOT을 붙인다.
WHERE은 여러 조건을 동시에 적용할 수 있으며, 조건의 개수에는 제한이 없다. 
두 조건을 연결하여 둘 다 참인 데이터를 조회한다. 

 

 

Q. 회원 정보 테이블 users에서
가입 일시(created_at)가 2010-12-01부터 2011-01-01까지인 회원 정보를 출력해보자
SELECT *
	FROM users
    WHERE created_at BETWEEN "2010-12-01" AND "2011-01-01"
    ;

 

Q. 회원 정보 테이블 users에서 거주 국가(country)가 이름이
s로 시작하지 않는 회원 정보만 추출해 보자
SELECT *	
	FROM users
    WHERE country NOT LIKE "S%"
    ;

 

Q. 회원 정보 테이블 users에서
가입 일시created_at) 컬럼 값이 null 이 아닌 결과만 출력해 보자
SELECT *
	FROM users
    WHERE created_at IS NOT null
    ;

 

Q. 주문 정보 테이블 orders에서
주문 일자(order_date)가 2015-07-01부터 2015-10-31까지가 아닌 정보만 추출하자
SELECT *
	FROM orders
    WHERE order_date NOT BETWEEN "2015-07-01" AND "2015-10-31"
    ;

3. 어떤 순서로 볼까? -ORDER BY

기본적으로 오름차순 정렬 
컬럼을 기준으로 행 데이터를 오름차순, 내림차순 정렬
ORDER BY [기준 컬럼] [ASC/ DESC] 형태로 정리 

 

Q. 회원 정보 테이블 users에서 가입 일시(created_at) 기준으로 내림차순 정렬하여 출력해 보자
SELECT *
	FROM users
    ORDER BY created_at DESC
    ;

 

Q. 주문 상세 정보 테이블 orderdetails에서 먼저 제품 아이디(product_id)를 기준으로 내림차순 정렬하고,
같은 제품 아이디 내에서는 판매 수량(quantity)값을 기준으로 오름차순 정렬하여 모든 칼럼 출력하라
SELECT *
	FROM orderdetails
    ORDER BY product_id DESC, quantity ASC
    ;

 

💡 실무 적용!
Q. 최근 한 달 이내에 도서 구독 멤버십에 가입한 회원만 추출해 보자
SELECT *
	FROM 회원정보
    WHERE 가입일자 >= (오늘일자-1달)
    	AND 멤버십 가입여부 = 1;

 

Q. 2023-08-01에 주문한 내역 중
쿠폰 할인이 적용된 내역만 추출한다
SELECT *
	FROM 주문정보
    WHERE 주문일자="2023-08-01"
    	AND 쿠폰할인금액 >0;

 

 

4. 데이터를 그룹으로 묶어서 계산하자! 

엑셀의 함수처럼, 데이터를 원하는 형태로 적절히 가공해서 사용할 때 사용한다! 

 

(1) COUNT

  • 지정된 컬럼의 null 을 제외한 행 수를 반환하는데, 이때 중보 값은 제거하지 않고 센다
  • DISTINCT와 함께 쓰면 중복을 제외할 수 있다.

 

Q. 제품 정보 테이블 products에서 최저가를 구해 보자
SELECT MIN(price)
	FROM products
    ;

 

(2) SUBSTR

  • 문자열을 지정된 시작 위치부터 지정된 길이만큼 자른 결과 반환
  • 입력 값으로 세 개의 값을 넣어야 하는데, 각각 '대상 컬럼', '시작 위치', '추출할 문자 개수'를 넣어야 한다.
💡 실무 적용!
Q. 회원 정보 테이블 users에서 회원의 가입일자(day), 가입년월(month), 가입일시(created_at)을 출력해 보자
SELECT SUBSTR(ceated_at,1,10) AS day
	, SUBSTR(created_at,1,7) AS month
    , created_at
    FROM users
    ;

 

(3) 일반 함수(데이터 가공 혹은 변환)

함수명 의미 사용방법
ROUND 소수점 자리를 지정한 자릿수까지 반올림하여 반환 ROUND ([칼럼명] , [표시할 소수점 자릿수])
SUBSTR 문자열을 지정한 시작 위치로부터 지정한 문자 개수만큼 가져와 반환 SUBSTR ([칼럼명], [시작 위치], [가져올 문자 개수])
LENGTH 문자열의 길이 변환 LENGTH ([칼럼명])
UPPER 알파벳 문자열을 대문자로 변경 UPPER ([칼럼명])
LOWER 알파벳 문자열을 소문자로 변경 LOWER ([칼럼명])

 

Q. 회원 정보 테이블 Users에서
이메일(username)의 길이가 17자리 이하인 회원 수를 중복 없이 센 값을 출력하자
SELECT COUNT(DISTINCT id) AS userCNT
	FROM users
    WHERE LENGTH(username) <= 17
    ;

 

(4) GROUP BY

  • 집계 함수는 특정 컬럼을 기준으로, 데이터를 그룹화한 후, 그룹별로 집계 함수를 적용하는 방식으로 동작한다.
  • GROUP BY 는 집계 함수와 함께 사용되며, GROUP BY의 기준 컬럼은 SELECT에서 집계 함수를 사용할 때 묶어서 계산을 수행하는 기준이다. 
  • GROUP BY에 두 개 이상의 기준 컬럼을 추가하면 데이터가 여러 그룹으로 나뉘고, 지정된 컬럼의 순서에 따라 결과가 달라진다. 따라서 중요한 기준을 앞에 배치해서 그룹화를 먼저 수행해야 한다. 

 

Q. 회원 정보 테이블 users에서
국가(country)별 회원 수를 구해 보자
SELECT country, COUNT(DISTINCT id) AS uniqueUserCnt
	FROM users
    GROUP BY country
    ;

 

 

💡실무 적용!
Q. 회원 정보 테이블 Users에서 거주 국가(country)가 한국(Korea)인 회원 중
마케팅 수신에 동의한 회원 수를 구해보자.

(동의:1, 비동의:0)
SELECT COUNT(DISTINCT id) AS uniqueUserCnt
	FROM users
    WHERE country='KOREA' AND is_marketing_agree=1
    ;

 

💡 실무 적용!
Q. 회원 정보 테이블 users에서 월별 가입 회원 수를 구해 보자 가입 일시(created_at) 컬럼을 활용하고, 최신 순으로 정렬
SELECT SUBSTR(created_at,1,7) AS month, COUNT(DISTINCT id) AS
# 가입 일시를 정제해주기 위해 앞의 7의자리까지만 필요하다. 따라서 1번째부터 7번째자리까지 원하는만큼 잘라서 보여준다
uniqueUserCnt
	FROM users
    GROUP BY SUBSTR(created_at,1,7)
    ORDER BY month DESC
    ;

 

💡 실무 적용!
Q. 주문 정보 테이블 orders에서 직언 아이디(staff_id)별, 회원 아이디(user_id)별로 주문 건수를 출력하라
(단, 직원 아이디 기준 오름차순으로 먼저 정렬한 뒤 주문 건수 기준 내림차순으로 정렬)

 

SELECT staff_id, user_id, COUNT (*) AS cnt
	FROM orders
    GROUP BY staff_id, user_id
    ORDER BY staff_id, cnt DESC
    ;

 

 

💡 실무 적용!
Q. 주문 정보 orders테이블에서 월별로 주문한 회원 수 출력
(주문 일자(order_date)컬럼 활용하고, 최신 순 정렬)
SELECT SUBSTR(order_date,1,7) AS month, COUNT(DISTINCT user_id)
AS CntUser
	FROM orders
    GROUP BY month
    ORDER BY month DESC
    l

 

(4) HAVING

 

  • GROUP BY가 실행된 이후의 집계 함수 값을 필터링한다.
  • GROUP BY 가 SELECt문에 없다면 사용할 수도 없을 뿐더러 사용할 필요도 없다.
  • HAVING은 WHERE같이 조건 연산자로 여러 조건문을 연결할 수 있고, 연산이 적용되지 않은 기본 컬럼은 HAGING조건문에서 사용할 수 없다. 

 

💡 실무 적용!
Q. 주문 정보 테이블 orders에서 회원별 주문 건수 출력

(단, 주문 건수가 7건 이상인 회원의 정보만 추출하고 주문 건수 기준으로 내림차순 정렬하라 회원 아이디(user_id)와 주문 아이디(id)컬럼 활용

 

SELECT user_id, COUNT(DISTINC id) AS ordCNT
	FROM orders
    GROUP BY user_id
    HAVING ordCNT >=7
    ORDER BY ordCNT DESC
    ;

 

💡 실무 적용!
Q. 2023-08에 음식 분류별 주문 건수 집계한다
SELECT 음식분류, COUNT(DISTINCT 주문아이디) AS 주문건수
	FROM 주문정보
    WHERE 주문시간(월) = '2023-08'
    GROUP BY 음식분류
    ORDER BY 주문건수 DESC
    ;

 

5. 데이터를 내가 원하는 대로 합쳐보자! 

✔️ 두 테이블을 하나로 묶으려면 두 테이블에 공통된 key가 존재해야 한다. 
✔️ FROM에 JOIN이 적용된 후에도 단일 테이블에 명령을 내리는 것처럼 쿼리를 작성하면 된다.
✔️ 두 컬럼 값이 일치하는 데이터만 가져오도록 비교 기준을 설정하는 것이 ON

 

 

(1) INNER JOIN

  • 두 테이블의 키 값이 일치하는 행의 정보만 가져오는 것 
  • 교집합에 해당하는 정보만 가져온다
  • FROM [테이블1] a INNER JOIN [테이블2] b ON a. [테이블1의 Key 칼럼] = b. [테이블2의 key칼럼] 
  • 조건으로 제시된 키 값이 일치하는 행의 정보만 표시하며, 일치하는 값이없는 행은 결과에서 제외한다 -> 교집합!

 

(2) LEFT JOIN (LEFT OUTER JOIN)

  • 두 테이블의 교집합과 교집합에 속하지 않는 왼쪽 차집합을 불러온다. 
  • 즉, 왼쪽에 있는 테이블 값을 모두 가져오기 때문에 LEFT OUTER JOIN이라고 한다. 
  • 한쪽 테이블의 값을 보전해야 할 때가 많아서 실무에서 자주 사용이 된다. 
  • 두 테이블을 결합하되, ON의 조건에 만족하지 않는 데이터도 모두 출력한다는 점에서 INNER JOIN과 다르다

 

Q. 회원 정보 테이블 users와 주문 정보 테이블 orders를 하나로 결합하여 출력해 보자
(단, 주문 정보가 없는 회원의 정보만 출력하자)

 

SELECT *
	FROM users u LEFT_JOIN orders o ON u.id=o.user_id
    WHERE o.id IS null
    ;

 

(3) CROSS JOIN 

  • 두 테이블 간의 모든 가능한 조합을 생성하는 데 사용된다.
  • ON 조건 없이 행의 모든 조합을 생성한다.
  • 실제 운영 환경에서는 CROSS JOIN을 제한하는 편이다. 컴퓨터에 가장 많은 연산을 요구하기 때문이다! 

(4) UNION

  • 컬럼의 형식과 개수가 같은 두 데이터 결과 집합을 하나로 결합하는 기능
  • 여러 가지 조건을 설정해야 하는 JOIN과 달리 UNION에서는 컬럼의 형식과 개수만 동일하면 결합이 가능하다.
  • 결합하는 두 결과 집합에 대해 중복 제거 기능이 포함되어 있어서 컬럼 값이모두 같다면 중복을 제외한 결과를 출력한다. 
  • UNION ALL 은 중복 제거 로직 없이 결합된 결과 값을 모두 출력하기 때문에 반복된 행을 확인할 수 있다. 
  • UNION과 UNION ALL 사용할 때 두 대상의 컬럼 형식이 일치하는지 반드시 확인해야 한다. 컬럼 순서, 컬럼명, 컬럼 값의 데이터 타입이 모두 같아야 정상적으로 동작하기 때문이다! 
  • 개별 대상에 WHERE을 사용한 이후 결합하는 것이 더 좋다

(5) 서브쿼리 (sub query) 

  • 쿼리 결괏값을 메인 쿼리에서 값이나 조건으로 사용하고 싶을 때 쓴다
  • 쿼리를 괄호로 감싸서 해당 쿼리의 결괏값을 메인 쿼리에서 활용할 수 있다. 
  • SELECT에서는 단일 집계 값을 신규 컬럼으로 추가하기 위해 서브 쿼리를 사용한다. 여러 개의 컬럼을 추가하고 싶을 때 서브 쿼리를 여러 개 작성하면 된다. 메인쿼리의 FROM에서 사요오딘 테이블이 아닌 테이블에서도 사용이 가능하기 때문에 불필요한 조인 수행을 줄일 수 있다. 

 

 

실무에서 놓치기 쉽지만 알아두면 써먹을 좋을 팁들! 


✔️ 어떤 테이블의 모든 정보를 스캔하는 '풀 스캔'은 특별한 상황이 아니라면 피해야 한다.

해당 테이블에 데이터가 많이 저장되어 있으면 과부하가 걸려 제때 처리하지 못하기 때문이다! 단순히 데이터를 파악하고 싶을 뿐이라면 쿼리의 마지막 줄에 LIMIT 을 추가하여 일부 데이터만 가져와서 확인하는 습관을 가지자 

 

✔️ 가능 여부를 나타내는 컬럼에서 주로 1은 TRUE, 0은 FALSE를 의미한다.

✔️ 실무에서는, UNION보다 UNION ALL 이 더 권장된다.

 UNION을 사용하면 대량의 데이터를 대상으로 중복 항목을 제거할 때 컴퓨터에 무리한 연산 부하를 줄 수 있기 때문이다. 

 

✔️ SQL 패턴 가이드! 

⭐️ 기준별로 연산된 값을 보고 싶을 땐??

▶︎ 데이터 그룹화하기 : GROUP BY + 집계 함수 

 

⭐️ 원본 테이블이 아닌, 쿼리를 실행한 결과 집합끼리 조합하고 싶을 땐?

▶︎ 데이터 결과 집합 결합하기 : JOIN + SUB QUERY

 

⭐️ 그룹화 기준 컬럼과 집계 연산을 수행할 컬럼이 서로 다른 테이블에 있을 경우엔?

▶︎ 테이블 결합 후 그룹화하기 : JOIN + GROUP BY

 

⭐️ 쿼리 결괏값을 다시 필터링 하고 싶거나, 쿼리 결괏값을 기반으로 동적 필터링을 하고 싶을 경우엔?

▶︎ 서브 쿼리로 필터링하기 : WHERE + SUB QUERY

 

⭐️ 같은 행동을 반복한 대상을 추출하고 싶을 경우엔?

▶︎ 리텐션 추출하기 : LEFT JOIN

 

💡 실무 적용!
Q. 주문 정보 테이블 Orders에서 2015-12에 주문한 회원 중 2016-01에도 주문한 회원의 비율을 출력해보자.
(회원 아이디(user_id), 주문일자(order_date)컬럼을 활용해보자)
SELECT ROUND(COUNT(DISTINCT re.user_id) / COUNT(DISTINCT fst.user_id),
	AS retentionRatio
    FROM (
    	SELECT user_id
        	FROM orders
            WHERE order_date BETWEEN '2015-12-01' AND '2015-12-31' 
          ) fst
     LEFT JOIN
     (
     	SELECT user_id
        	FROM orders
            WHERE order_date BEWEEN '2016-01-01' AND '2016-01-31'
      ) re
      ON fst.user_id = re.user_id
      ;

 

💡 실무 적용!
Q. 피자와 초밥 메뉴의 주문 건수와 매출액을 구해 하나의 테이블로 추출한다.

 

SELECT '피자' AS 메뉴, COUNT (*) AS 주문건수, SUM(가격) AS 매출
	FROM 주문정보 WHERE 메뉴아이디 = 1
UNION ALL
SELECT '초밥' AS 메뉴, COUNT (*) AS 주문건수, SUM(가격) AS 매출
	FROM 주문정보 WHERE 메뉴아이디 = 2;

 


📚책 총평! 

✨✍🏻 서비스기획/ PM을 준비하고 있는 사람이라면 한번씩 봐두면 좋을 책! 

기초부터 알려주는 이론 내용과 실무에서 직접 쓰일 법한 예제 문제들을 잘 다루고 있어 기획자들이라면 한번씩 보고가도 좋을 듯하다! 

특히 책이 굉장히 꼼꼼하게 되어있어서 다양한 예제들과 패턴, 실무 학습법을 알려주고 있다. 

내가 리뷰한 내용들 뿐만 아니라 굉장히 다양한 예제들이 많아 직접 읽어보면 좋을듯하다!~~

 

'데이터' 카테고리의 다른 글

[데이터분석] 유저들의 데이터 흔적을 찾아라!  (0) 2025.10.02
[데이터] 데이터로 인사이트 얻기 - 데이터 리터러시 리뷰 (2)  (1) 2025.09.14
[데이터] 데이터로 인사이트 얻기 - 데이터 리터러시 리뷰  (4) 2025.09.14
'데이터' 카테고리의 다른 글
  • [데이터분석] 유저들의 데이터 흔적을 찾아라!
  • [데이터] 데이터로 인사이트 얻기 - 데이터 리터러시 리뷰 (2)
  • [데이터] 데이터로 인사이트 얻기 - 데이터 리터러시 리뷰
hye2 이야기
hye2 이야기
앱 서비스를 좋아하는 PM 블로그입니다
  • hye2 이야기
    hye2story 님의 블로그
    hye2 이야기
  • 전체
    오늘
    어제
    • 분류 전체보기 (21)
      • 데이터 (4)
      • 내 기록 (1)
      • 프로덕트 서비스 (1)
      • 인사이트 (4)
      • 이커머스 (0)
      • AI (5)
      • UI UX (3)
      • 서비스기획 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    에이블리 운세
    애플 앱스토어 수상작
    서비스 기획
    2025 앱스토어 수상작
    한국인이 많이 사용한 앱
    2025 앱
    알라미 기획
    사용자 행동 데이터 분석
    AI 기획
    ui ux 분석
    올해의 앱
    실무SQL
    2026 기술트렌드
    기획자의 SQL
    유저 타겟팅
    2026 AI 트렌드
    지그재그 운세
    커뮤니티 서비스 키우기
    PM SQL
    서비스기획자 데이터분석
    구글 GEO
    리텐션 높이기
    PM 데이터분석
    마켓컬리전략
    앱 서비스 기획
    2026년도 AI 전망
    배달의민족 기획
    서비스기획
    PM 데이터 분석
    RAG 기획
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
hye2 이야기
[데이터분석] SQL 실무 예제로 공부하기-기획자의 SQL 책 리뷰
상단으로

티스토리툴바