데이터 분석을 위한 중급 SQL
SQL 조건문
CASE 문
SELECT CASE
WHEN id = 1 THEN "음료"
WHEN id = 2 THEN "조미료"
ELSE "기타"
END as 'categoryName', * -- 아스타로 전체 테이블 확인
FROM products
- WHEN안에 조건 여러 개 작성도 가능하다. (WHEN 조건1 AND 조건 2 THEN “결과”)
- categoryName이라는 새로 만든 컬럼으로 group by도 가능
SELECT CASE
WHEN id = 1 THEN "음료"
WHEN id = 2 THEN "소스"
ELSE "그외"
END as 'categoryName', AVG(price)
FROM products
GROUP BY categoryName
[해커랭크 문제 풀이]
https://www.hackerrank.com/challenges/what-type-of-triangle/problem?h_r=internal-search
Type of Triangle
어려웠는데, 문제를 이해하는 게 더 어려웠던 문제
정답
SELECT CASE
WHEN A = B and B=C THEN "Equilateral"
WHEN A + B <= C or B+C <= A or C+A <= B THEN "Not a triangle"
WHEN A = B or B = C or C=A THEN "Isosceles"
ELSE "Scalene"
END
FROM TRIANGLES
- case 조건의 순서가 중요하다!!
CASE를 활용한 테이블 피봇
- 예를 들면 카테고리별 평균값으로 새로운 테이블 생성할 수 있다.
SELECT AVG(CASE
WHEN categoryID = 1 THEN price
ELSE NULL
END) AS category1_price
AVG(CASE
WHEN categoryID = 2 THEN price
ELSE NULL
END) AS category2_price
AVG(CASE
WHEN categoryID = 3 THEN price
ELSE NULL
END) AS category3_price
FROM products
--카테고리가 1인 경우엔 category1_price 열에 AVG(price)컬럼을 출력
-- AVG()의 위치 확인!
[해커링크 문제 풀이]
Top Earners
틀린답
SELECT MAX(months*Salary), count(name)
FROM Employee
where salary*months = max(months*salary) --??
-- 1. 가져올 값 중 하나만 조건을 적용하고 싶다
-- 2. 조건 어떻게 써야할지 모르겠다
정답
SELECT months*salary as earnings, COUNT(*)
FROM Employee
GROUP BY earnings
ORDER BY earnings DESC
LIMIT 1
- 최댓값이라는 말에 꽂혀서 MAX에 갇히지 말자.
- 그룹바이가 꼭 여러 개 그룹이 아니라 값 하나씩도 될 수 있다는 것을 생각하자
RFM Segmentation
RFM은 고객 세분화 모형 중 실무에서 자주 사용하는 모형이다.
- Recency: 얼마나 최근에 구매했는지
- Frequency: 얼마나 자주 구매했는지
- Monetary: 얼마나 많은 금액을 구매했는지
→ RFM 구분을 바탕으로 CRM마케팅에 활용할 수있다. (푸쉬 대상, 수단, 내용 등 조정)
-> 구분을 나누는 기준과 단계는 서비스별로 천차만별이다.
이러한 RFM분석을 조건문을 활용해서 나누어 볼 수 있다.
CASE문 (여러 개 조건 가능)
SELECT CASE
WHEN (A조건) THEN (A조건이 True 일 때)
WHEN (B조건) THEN (B조건이 True 일 때)
ELSE (위의 조건이 모두 False 일 때)
END
IF문 (단일 조건만 가능)
-- IF(조건, 조건이 True일 때, False일 때)
고객 분류하기 (if 활용 버전)
SELECT IF(last_order_date >= '2020-12-01', 1, 0) AS recency
, IF(cnt_orders >= 3,1,0) AS frequency
, IF(sum_sales >= 500, 1, 0) as monetary
, count(customer_id) as customers
from customer_stats
group by recency, frequency, monetary
order by recency desc, frequency desc, monetary desc
solvesql 플랫폼
RFM분석 1
select customer_id, last_order_date, cnt_orders, sum_sales,
case
when last_order_date >= '2020-12-01' then 1
else 0
end as recency,
case
when cnt_orders >= 3 then 1
else 0
end as frequency,
case
when sum_sales >= 500 then 1
else 0
end as monetary
from customer_stats
RFM 분석 떠나간 VIP
select case
when last_order_date >= '2020-12-01' then 1
else 0
end as recency,
case
when cnt_orders >= 3 then 1
else 0
end as frequency,
case
when sum_sales >= 500 then 1
else 0
end as monetary
, count(customer_id) as customers
from customer_stats
group by recency, frequency, monetary
having frequency = 1 and monetary = 1
order by recency desc
가구 판매의 비중이 높았던 날 찾기(어려움)
SELECT order_date
,count(distinct case when category = "Furniture" then order_id END) as furniture
,Round((count(distinct case when category = "Furniture" then order_id END) / count(distinct order_id)),4) * 100 as furniture_pct
FROM records
GROUP BY order_date
having count(distinct order_id) >= 10 and furniture_pct >= 40
ORDER BY furniture_pct desc, order_date asc
distinct 잊지 말기!!
SQL로 피봇테이블로 만들어 활용할 수 있다.
GROUP BY, SELECT 연산을 활용, CASE문도 활용 가능