일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- GA4
- pandas
- 크롤링
- cross join
- 프롬프트 엔지니어링
- Python
- 전처리
- SQL
- streamlit
- 클러스터링
- lambda
- 기초통계
- 히트맵
- 군집화
- 서브쿼리
- 머신러닝
- If
- 데이터 분석
- 태블로
- Chat GPT
- da
- 기초프로젝트
- jd
- data analyst
- 최종 프로젝트
- 팀프로젝트
- 프로젝트
- SQLD
- 시각화
- 데이터분석
- Today
- Total
세조목
SQL 예제 풀이(Leetcode - Confirmation Rate) 본문
https://leetcode.com/problems/confirmation-rate/description/
Signups와 Confirmations 두 테이블이 있다.
두 테이블을 가지고서 각 유저별 confirm받은 비율을 구하는 것이 문제의 요구사항이다.
confirm받을 비율을 구하기 위해서는
각 유저별로 Confirmations 테이블의 action 컬럼 속성값이 confirmed로 적혀있는 수를
전체 action 횟수로 나눠주면된다.
예를 들어
user_id 2의 경우 confirm된건 한 번이고,
전체 action은 두 번이기때문에
1 / 2 해서 confirmation ratio는 0.5가 된다.
전체 action의 수는 전체 테이블을 user_id로 그룹화해서 user_id를 count하면 될 것 같다.
문제는 confirm받은 action의 횟수인데
조건을 걸어야하기때문에 별도의 테이블을 만들어 준다.
* 본 테이블에 조건을 걸면 전체 action의 수를 구할 수 없음
SELECT SI.USER_ID,
COUNT(CON.ACTION)
FROM SIGNUPS SI LEFT JOIN CONFIRMATIONS CON ON SI.USER_ID = CON.USER_ID
WHERE CON.ACTION = 'CONFIRMED'
GROUP BY SI.USER_ID
이렇게 SIGNUPS 테이블과 CONFIRMATIONS 테이블을 LEFT JOIN하여
ACTION 컬럼의 속성값이 CONFIRMED인 USER의 수를 COUNT한다.
* 이 쿼리의 별명은 앞으로 CNT다.
그런 다음
이 쿼리와 전체의 경우를 볼 수 있는 쿼리를 FROM절에서 JOIN한 후 비율을 구한다.
전체의 경우를 볼 수 있는 쿼리는 아래와 같다.
* 이 쿼리는 편의상 ALL이라고 표현하겠다.
SELECT *
FROM SIGNUPS SI LEFT JOIN CONFIRMATIONS CON ON SI.USER_ID = CON.USER_ID
GROUP BY SI.USER_ID
모든 USER_ID가 포함되어야하기때문에 ALL을 왼쪽에 두고 LEFT JOIN한다.
SELECT *
FROM SIGNUPS SI LEFT JOIN CONFIRMATIONS CON ON SI.USER_ID = CON.USER_ID LEFT JOIN
(
SELECT SI.USER_ID,
COUNT(CON.ACTION) CON_CNT
FROM SIGNUPS SI LEFT JOIN CONFIRMATIONS CON ON SI.USER_ID = CON.USER_ID
WHERE CON.ACTION = 'CONFIRMED'
GROUP BY SI.USER_ID
) CNT ON SI.USER_ID = CNT.USER_ID
이렇게 쿼리를 작성했을때의 결과값은 아래와 같다.
전체 USER_ID와 CONFIRM된 횟수 모두 확인할 수 있다.
* 왼쪽 빨간 테두리 = 전체 USER_ID / 오른쪽 빨간 테두리 = CONFIRM된 횟수
CONFIRM된 횟수는 이미 COUNT되어졌으니 CNT.CON_COUNT 그대로 사용하면 되고
그 수를 전체 유저수를 COUNT한 COUNT(SI.USER_ID)로 나눠주면된다.
이를 반영한 쿼리와 결과값은 아래와 같으며
문제에서 CONFIRMATION RATE를 소수점 둘째자리까지만 표시하라고 했기때문에
ROUND함수를 적용해주면 된다.
SELECT SI.USER_ID,
IF(CNT.CON_CNT / COUNT(SI.USER_ID) IS NOT NULL, ROUND((CNT.CON_CNT / COUNT(SI.USER_ID)), 2), 0) CONFIRMATION_RATE
FROM SIGNUPS SI LEFT JOIN CONFIRMATIONS CON ON SI.USER_ID = CON.USER_ID LEFT JOIN
(
SELECT SI.USER_ID,
COUNT(CON.ACTION) CON_CNT
FROM SIGNUPS SI LEFT JOIN CONFIRMATIONS CON ON SI.USER_ID = CON.USER_ID
WHERE CON.ACTION = 'CONFIRMED'
GROUP BY SI.USER_ID
) CNT ON SI.USER_ID = CNT.USER_ID
GROUP BY SI.USER_ID
* SI.USER_ID로 그룹화해주는 것도 잊어서는 안 된다.
'데이터 분석 공부 > SQL' 카테고리의 다른 글
SQL 예제(Consecutive Numbers)(Lead 함수) (0) | 2024.02.22 |
---|---|
SQL 예제(Triangle Judgement) (0) | 2024.02.21 |
SQL 정리(Join의 기준)(24.02.01) (0) | 2024.02.01 |
SQL 정리(프로그래머스 - '주문량이 많은 아이스크림들 조회하기')(24.01.22) (0) | 2024.01.22 |
SQL 정리(프로그래머스 - '우유와 요거트가 담긴 장바구니')(24.01.22) (0) | 2024.01.22 |