rubus0304 님의 블로그

[QCC 4회차] 본문

Data Analyst/daily

[QCC 4회차]

rubus0304 2024. 12. 13. 15:09

[4기] QCC - 4회차

 

[4기] QCC - 4회차 | Notion

셋팅 안내

teamsparta.notion.site

 

 

문제 1 (下)


  • 테이블 설명 :

stores 테이블은 각 매장에 대한 정보를 담고 있습니다. 테이블 구조는 다음과 같으며, STORE_NAME, REGION_NAME, SALES, EMPLOYEES, OPEN_DATE, TYPE은 각각 매장 ID, 지역 이름, 매출, 직원 수, 개점일, 매장 유형을 나타냅니다.

컬럼명 타입 설명

STORE_ID VARCHAR 매장 ID (PK)
REGION_NAME VARCHAR 지역 이름
SALES NUMERIC 매출
EMPLOYEES INT 직원 수
OPEN_DATE DATE 개점일
TYPE VARCHAR 매장 유형

  • 분석해야 할 내용은 다음과 같습니다 :

지역별매출이 가장 높은 매장을 조회하는 SQL 문을 작성해주세요. 단, 해당 지역에 매장이 두 개 이상인 경우만 결과에 포함해주세요. 결과는 지역 이름을 기준으로 오름차 정렬해주세요.

 

출력 값 예시

stores 테이블이 다음과 같다면 :

STORE_ID REGION_NAME SALES EMPLOYEES OPEN_DATE TYPE

1 Seoul 1000.5 10 5/1/2020 Retail
2 Seoul 1500.75 15 3/15/2019 Retail
3 Seoul 100.00 5 3/12/2020 Retail
4 Busan 2000 20 6/10/2021 Wholesale
5 Daegu 1200.25 12 7/30/2018 Retail
6 Daegu 900 8 9/20/2020 Retail
7 Incheon 500 5 1/15/2022 Retail
  • Seoul 지역에는 매장이 3 개 있으며, 매출이 가장 높은 매장은 STORE_ID 2입니다.
  • Busan 지역에는 매장이 하나만 있습니다. 따라서 결과에 포함되지 않습니다.
  • Daegu 지역에는 매장이 2 개 있으며, 매출이 가장 높은 매장은 STORE_ID 5입니다.
  • Incheon 지역에는 매장이 하나만 있습니다. 따라서 결과에 포함되지 않습니다.

 

 

 

정답  (생각보다 단순)

 

select region_name,

max(sales) highest_sales

from stores

group by 1

having count(distinct store_id) > 1

order by 1;

 

 

문제 2 (中)


  • 테이블 설명 :

payments 테이블은 사용자의 결제 정보를 포함합니다. 테이블 구조는 다음과 같으며, ID, USER_ID, AMOUNT, PAY_DATE, 그리고 PAYMENT_TYPE은 각각 결제 ID, 사용자 ID, 결제 금액, 결제 날짜, 결제 유형(카드, 현금 등)을 나타냅니다.

컬럼명 타입 설명

ID INT 결제 ID (PK)
USER_ID VARCHAR 사용자 ID
AMOUNT INT 결제 금액
PAY_DATE DATETIME 결제 날짜
PAYMENT_TYPE INT 결제 유형 (0: 현금, 1:카드)

orders 테이블은 사용자의 상품 배송 정보를 포함합니다. 테이블 구조는 다음과 같으며, ID, USER_ID, ORDER_DATE, 그리고 ITEM은 각각 주문 ID, 사용자 ID, 주문 날짜, 주문한 상품명을 나타냅니다. 해당 테이블의 USER_ID 는 payments 테이블의 USER_ID랑 동일합니다.

 

 

  • 분석해야 할 내용은 다음과 같습니다 :

최근 특정 사용자들이 결제를 하지 않고 상품을 주문하거나, 결제를 하지 않은 시점에 이미 상품을 주문하는 버그가 발견되었습니다. 🐞 해당 버그를 악용한 사용자를 파악하기 위해 SQL 문을 작성해주세요. 다음 조건에 해당되는 사용자 수를 출력해주세요 :

  • 결제를 하지 않고 상품을 주문한 사용자
  • 첫 번째 결제일보다 이전에 상품을 주문한 사용자

 

출력 값 예시

payments 테이블이 다음과 같고 :

ID USER_ID AMOUNT PAY_DATE PAYMENT_TYPE

1 user1 3000 2023-01-23 10:00:00 0
2 user3 5000 2023-01-23 14:00:00 1
3 user5 7000 2023-02-23 12:00:00 0

orders 테이블이 다음과 같다면 :

ID USER_ID ORDER_DATE ITEM

1 user1 2023-02-23 09:30:00 Laptop
2 user2 2023-01-23 15:45:00 Smartphone
3 user4 2023-01-23 17:20:00 Headphones
4 user5 2023-01-23 08:00:00 Monitor
  • user1은 결제 후 상품을 주문했으므로 버그와 무관합니다.
  • user2는 결제를 하지 않고 상품을 주문했습니다. 버그를 악용했습니다.
  • user4는 결제를 하지 않고 상품을 주문했습니다. 버그를 악용했습니다.
  • user5는 첫 번째 결제일 이전에 상품을 주문했습니다. 버그를 악용했습니다.

< 내 답 >

SELECT count(distinct o.USER_ID) cnt

from orders o left join payments p on o.user_id = p.USER_ID

where p.USER_ID is null or o.ORDER_DATE < (select min(pay_date) from payments p2 where p2.user_id=o.user_id)

 

 

<정답>

 

# with 로 first_payment 만들기

 

with first_payment as(

select user_id, min(pay_date) first_pay_date

from payments

group by 1

)

select o.*, fp.*

from orders o left join first_payment fp on o.USER_ID = fp.user_id

where order_date < first_pay_date

 

#버그 2

with first_payment as(

select user_id, min(pay_date) first_pay_date

from payments

group by 1

)

select o.*, fp.*

from orders o left join first_payment fp on o.USER_ID = fp.user_id

where order_date < first_pay_date

 

# 버그 1

with first_payment as(

select user_id, min(pay_date) first_pay_date

from payments

group by 1

)

select o.*, fp.*

from orders o left join first_payment fp on o.USER_ID = fp.user_id

where fp.user_id is null

 

# 버그 1, 2 합치기

with first_payment as(

select user_id, min(pay_date) first_pay_date

from payments

group by 1

)

select o.*, fp.*

from orders o left join first_payment fp on o.USER_ID = fp.user_id

where fp.user_id is null or order_date < first_pay_date

 

 

# 고객 카운트 세기

with first_payment as(

select user_id, min(pay_date) first_pay_date

from payments

group by 1

)

select count(distinct o.USER_ID) cnt

from orders o left join first_payment fp on o.USER_ID = fp.user_id

where fp.user_id is null or order_date < first_pay_date

 

문제 3 (上)


  • 테이블 설명

cart_products 테이블은 쇼핑 카트에서 주문된 아이템에 대한 정보를 담고 있습니다. 테이블 구조는 다음과 같으며, ID, CART_ID, NAME, PRICE는 각각 제품 ID, 주문 번호, 제품 이름, 개별 제품 가격을 나타냅니다.

컬럼명 타입 설명

ID INT 제품 ID
CART_ID INT 주문 번호
NAME VARCHAR 제품 이름
PRICE INT 제품 가격 (원 단위)

  • 분석해야 할 내용은 다음과 같습니다 :

데이터 분석팀은 고객이 특정 상품 X를 구매했을 때 상품 Y도 함께 구매할 확률을 분석하고자 합니다. 이를 위해, 쇼핑 카트 데이터에서 서로 다른 두 제품 X와 Y가 같은 주문(CART_ID)에 포함된 주문 수를 확인하려고 합니다.

  • 제품 X와 Y가 같은 주문에 포함된 경우를 계산합니다.
  • 두 제품은 서로 다른 이름이어야 하며, 한 쌍의 경우(예: Coffee와 Sausages)는 다른 순서(예: Sausages와 Coffee)로도 포함됩니다.
  • 결과는 각 제품 쌍과 해당 제품이 함께 포함된 주문 수를 반환해야 합니다.
  • 제품 이름 X와 Y를 기준으로 알파벳 순으로 오름차순 정렬합니다.

 

출력 값 예시

cart_products 테이블이 다음과 같다면 :

ID CART_ID NAME PRICE

1 1 Coffee 3000
2 1 Sausages 4000
3 1 Vegetable 2000
4 2 Coffee 3000
5 2 Bread 1500
6 2 Sausages 4000
7 3 Vegetable 2000
8 3 Bread 1500

<내 답>  butter coffee /  coffee  butter 값 중복제거

select least(c1.name, c2.name) name_x,

greatest(c1.name, c2.name) name_y,

count(distinct c1.cart_id) orders

from cart_products c1 join cart_products c2 on c1.cart_id = c2.cart_id and c1.name <> c2.name

group by 1,2

order by 1 asc, 2 asc

 

 

 

< 정답 >   butter coffee  / coffee  butter   값 중복도 그대로 포함!

 

Step 1 

select c1.cart_id cart_id_x, c1.name cart_name_x,

c2.cart_id cart_id_y, c2.name cart_name_y

from cart_products c1 join cart_products c2 on c1.cart_id = c2.cart_id and c1.name != c2.name

order by 1, 3

 

Step 2

 

select c1.name cart_name_x, c2.name cart_name_y, count(distinct c1.cart_id) order_count

from cart_products c1 join cart_products c2 on c1.cart_id = c2.cart_id and c1.name <> c2.name

group by 1, 2

order by 1, 2

 

'Data Analyst > daily' 카테고리의 다른 글

[태블로 과제해설]  (0) 2024.12.16
[코트카타 103]  (0) 2024.12.16
오늘은 새로운 팀 만난 날~  (0) 2024.12.10
[프로젝트 5주차]  (0) 2024.12.06
[프로젝트 4일차]  (1) 2024.12.04