내일배움캠프/TIL

[TIL]250107_QCC 2회차 문제풀이, 코드카타

dydatablog 2025. 1. 7. 21:29
728x90

FACTS : 지난번 결석한 날짜에 하필 QCC를 진행했어서 늦게나마 혼자서 문제를 풀어봤다.

시간내에 전부 다 풀지는 못했고,, 20분정도 더 시간을 써서 2문제를 풀었다.

FEELINGS 

잊을만하면 다시 돌아오는 SQL.. 파이썬 판다스에게 뚜들겨 맞다가 SQL 문제를 풀면 살짝 편안한 기분도 들지만 아직 여러 테이블을 합쳐서 결과값을 내야할 때는 머리가 안돌아간다. SQL도 파이썬도 코드를 짧고 간결하게 써보는 연습을 따로 진행해봐야겠다는 생각이 많이 드는 요즘이다.

- FINDINGS :

 문제1) 자꾸 중복값 제거 distinct를 안한다..전체 데이터 수에 영향이 가는 부분이니까 신경쓰기

 문제2) 여러가지 테이블을 join해야하는 부분에서 잠시 머리가 안돌아가서 종이에 적어가면서 풀이는 생각했다. 뽑아내야하는 결과값에 sales_customer 테이블은 필요 없는줄 알았더니 공통 키 값 때문에 결국은 4개의 테이블을 다 써야한다는걸 알아내는데까지 꽤나 시간이 걸려 버렸다..ㅎ


문제1

당신은 마케팅 팀의 일원으로서, 최근에 진행된 이메일 프로모션 캠페인에 관심이 있습니다. 해당 프로모션에 동의한 고객 수를 추산해야 합니다.

Person_Person 테이블을 사용하여 다음 조건을 만족하는 고객의 수를 구하세요 :

  1. 이메일 프로모션에 “동의”한 고객
  2. 해당 고객들 중 "개인(소매)" 고객의 수
# 내 풀이
SELECT COUNT(BusinessEntityID) as customer_count
FROM Person_Person
WHERE emailpromotion != 0
AND persontype = 'IN'

 

# 정답 예시	
SELECT COUNT(DISTINCT BusinessEntityID) as customer_count
FROM Person_Person
WHERE emailpromotion != 0
AND persontype = 'IN'

 

문제2

당신의 회사는 지난 2011년 10월 동안 자사 제품을 많이 주문한 고객들에게 특별 할인 쿠폰을 제공할 예정입니다. 이를 위해 2011년 10월 한 달 동안 회사 제품을 주문한 고객을 조회하고 구매수량별로 고객등급을 매기려 합니다. 결과는 총 주문 수량을 내림차순으로 정렬해주세요.

Sales_SalesOrderHeader, Sales_SalesOrderDetail, Sales_Customer, Person_Person 테이블을 사용하여 다음 조건을 만족하는 고객 목록을 구하세요:

  1. 주문 날짜가 “2011-10-01 부터 2011-10-31 사이”에 해당
  2. 고객의 총 주문 수량에 따라 5가지 등급으로 분류
    1. VIP : 100 개 이상
    2. GOLD : 70 개 이상 100 개 미만
    3. SILVER : 40 개 이상 70 개 미만
    4. BRONZE : 20 개 이상 40 개 미만
    5. BASIC : 20 개 미만
  3. 해당 고객들의 기본 정보를 포함, 총 주문 수량 기준 내림차순 정렬하여 출력
#작성한 코드
SELECT ssoh.CustomerID,
	pp.FirstName ,
	pp.LastName,
	sum(ssod.OrderQty) as total_quantity,
	CASE WHEN sum(ssod.OrderQty) >= 100 THEN 'VIP'
		WHEN sum(ssod.OrderQty) >= 70 THEN 'GOLD'
		WHEN sum(ssod.OrderQty) >= 40 THEN 'SILVER'
		WHEN sum(ssod.OrderQty) >= 20 THEN 'BRONZE'
		ELSE 'BASIC' END AS 'customer_class'
FROM Sales_SalesOrderDetail ssod
JOIN Sales_SalesOrderHeader ssoh ON ssod.SalesOrderID = ssoh.SalesOrderID
JOIN Sales_Customer sc ON ssoh.CustomerID = sc.CustomerID 
JOIN Person_Person pp ON sc.PersonID = pp.BusinessEntityID
WHERE ssoh.OrderDate BETWEEN '2011-10-01' and '2011-11-01'
GROUP BY sc.CustomerID
ORDER BY 4 DESC

 

#예시 답안
SELECT c.customerid as customer_id
	, p.firstname as first_name
	, p.lastname as last_name
	, SUM(so.orderqty) AS total_quantity
	, case when SUM(so.orderqty) >= 100 then 'VIP'
	       when SUM(so.orderqty) >= 70 then 'GOLD'
	       when SUM(so.orderqty) >= 40 then 'SILVER'
	       when SUM(so.orderqty) >= 20 then 'BRONZE'
	       else 'BASIC' end as customer_class
FROM Sales_Customer c
INNER JOIN Person_Person p ON c.personid = p.businessentityid
INNER JOIN Sales_SalesOrderHeader soh ON c.customerid = soh.customerid
INNER JOIN Sales_SalesOrderDetail so ON soh.salesorderid = so.salesorderid
WHERE DATE(orderdate) BETWEEN '2011-10-01' AND '2011-10-31' -- datetime형식을 DATE()를 이용해 시간 정보를 없애고 10-31일 까지의 데이터만 추출 
GROUP BY c.customerid, p.firstname, p.lastname
ORDER BY total_quantity desc;

 

-> datetime형식은 시간까지 포함되어있는 데이터이므로 일별 기간을 추출할 때는 DATE()를 사용해서 필터링 하는 것이 훨씩 직관적이라서 보기 편했다.


코드카타

 

32. 내적

def solution(a, b):
    answer = 0
    for i in range(len(a)):
        result = a[i] * b[i]
        answer += result
    return answer
    
#다른 풀이
def solution(a, b):
    return sum([x*y for x, y in zip(a,b)])

# 다른 풀이 해설

zip() 함수는 두 개 이상의 iterable(여기서는 리스트 a와 b)를 병렬 튜플 형태로 묶어주는 함수

예시) a = [1,2,3]  b = [4,5,6]

zip(a,b) = [(1,4),(2,5),(3,6)]

 

 

34. 문자열 내림차순으로 배치하기

def solution(s):
    s = sorted(s,reverse = True)
    return "".join(s)

 

35. 부족한 금액 계산하기

def solution(price, money, count):
    answer = 0
    ans = 0
    for i in range(1, count + 1):
        answer += price * i
        ans = answer - money
    if ans < 0:
        return 0
    else:
        return ans
        
#다른 풀이
def solution(price, money, count):
    return max(0,price*(count+1)*count//2-money)

 

728x90