💥 CODEKATA
~ 70문제
오늘 집중이 너무 안되는 날이었음…
66) 조회수가 가장 많은 중고거래 게시판의 첨부파일 조회하기
SELECT
CONCAT("/home/grep/src/", uf.board_id, "/", uf.file_id, uf.file_name, uf.file_ext) AS file_path
FROM
used_goods_file uf
JOIN (
SELECT board_id
FROM used_goods_board
WHERE views = ( SELECT MAX(views) FROM used_goods_board)) ub
ON uf.board_id = ub.board_id
ORDER BY
uf.file_id DESC
SELECT
a.flavor
FROM (
SELECT
j.shipment_id, f.flavor,
SUM(f.total_order) sumfirst,
SUM(j.total_order) sumjuly,
SUM(f.total_order) + SUM(j.total_order) AS sum_total
FROM
first_half f LEFT JOIN july j ON f.flavor = j.flavor
GROUP BY
f.flavor
ORDER BY
sum_total DESC
) a LIMIT 3
# 1차 코드
SELECT
s.book_id, SUM(s.sales) sum_sales, b.author_id, b.category, b.price,
(SUM(s.sales) * b.price) AS total_sales
FROM
book_sales s JOIN book b ON s.book_id = b.book_id
WHERE
s.sales_date LIKE "2022-01-%"
GROUP BY
s.book_id

⇒ book_id 별로 총 매출액은 구했는데, 이제 저자가 같으면서 카테고리도 같은 컬럼의 total_sales를 더해야 함.
# 2차 코드
WITH total AS (
SELECT
s.book_id, b.author_id, b.category,
(SUM(s.sales) * b.price) AS sumprice
FROM
book_sales s JOIN book b ON s.book_id = b.book_id
WHERE
s.sales_date LIKE "2022-01-%"
GROUP BY
s.book_id
)
SELECT
a.author_id, a.author_name, t.category,
SUM(t.sumprice) as total_sales
FROM
author a LEFT JOIN total t ON a.author_id = t.author_id
GROUP BY
1, 2, 3
ORDER BY
a.author_id,
t.category DESC
⇒ 처음에 GROUP BY 를 t.category 만 했다가 아차차 하고 1,2,3 다 넣어버림
69) 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기
# 1차 코드
WITH fivecnt AS (
SELECT
car_id, count(car_id) as totalcnt
FROM
car_rental_company_rental_history
WHERE
start_date LIKE "2022-08-%" OR
start_date LIKE "2022-09-%" OR
start_date LIKE "2022-10-%"
GROUP BY
car_id
HAVING
count(car_id) >= 5
)
SELECT
DATE_FORMAT(h.start_date, "%m") as month,
f.car_id,
count(DATE_FORMAT(h.start_date, "%m")) records
FROM car_rental_company_rental_history h JOIN fivecnt f ON h.car_id = f.car_id
GROUP BY
1,2
ORDER BY
month, car_id DESC
⇒
음 결과 맞는 것 같은데 왜 틀렸다 하지
아 DATE_FORMAT() 으로 뽑으면 08월 이렇게 나오는데, 출력 결과에선 그냥 8 으로 되어있음.
그래서 MONTH() 사용으로 수정. LIKE도 BETWEEN으로 수정.
그리고 굳이 JOIN 안해도 될 것 같은데?
본문 절에서 날짜 제한 안했더니 다른놈들이 또 튀어나와서 틀린거였음. WITH를 빼자니 총 5번 렌탈한 결과가 안나오고 월 별로 5번 이상 구매한 놈들만 나옴…ㄱ- 두 번이나 써야 되나…?
# 2차 코드
# join 빼는 건 지피티의 도움을 받아서 where in 으로 처리하는걸 깨달음
WITH fivecnt AS (
SELECT
car_id
FROM
car_rental_company_rental_history
WHERE
start_date BETWEEN "2022-08-01" AND "2022-10-31"
GROUP BY
car_id
HAVING
count(car_id) >= 5
)
SELECT
MONTH(start_date) as month,
car_id,
count(1) records
FROM
car_rental_company_rental_history
WHERE
start_date BETWEEN "2022-08-01" AND "2022-10-31" AND
car_id IN (SELECT car_id FROM fivecnt)
GROUP BY
1, 2
ORDER BY
month, car_id DESC
WITH max_review_count AS (
SELECT MAX(cnt) AS max_cnt
FROM (
SELECT member_id, COUNT(*) AS cnt
FROM rest_review
GROUP BY member_id
) AS counts
)
SELECT
m.member_name, r.review_text, DATE_FORMAT(r.review_date, '%Y-%m-%d') AS review_date
FROM
rest_review r JOIN member_profile m ON r.member_id = m.member_id
WHERE
r.member_id IN (
SELECT member_id
FROM rest_review
GROUP BY member_id
HAVING COUNT(*) = (SELECT max_cnt FROM max_review_count)
)
ORDER BY
r.review_date, r.review_text
⇒
WITH 절로 리뷰수 제일 많은 MAX(member_id)의 갯수를 구하고,
본문 절 WHERE 에서 member_id 를 선택하는데, 기준이 MAX(member_id)인 id만 선택.
뭔가 너무 너지저분한 것 같은데 이게 최선인가…?
이 문제 이실직고. 풀다가 오늘 집중 너무 안돼서 문명의 도움을 좀 받음 ㅎㅎ…..나중에 다시 풀어봐야지
🔰 과제
개인과제 - 도전
더보기
더보기
문제 6 : 두 수의 합(인덱스 반환)
📌 요구 지식: 딕셔너리, 반복문, 조건문
배경:
목표 합을 만드는 두 원소의 인덱스를 빠르게 찾는 패턴 연습입니다.
목표:
정수 리스트 nums와 정수 target이 주어질 때, 합이 target이 되는 서로 다른 두 인덱스를 (i, j)로 반환하세요. (없으면 (-1, -1))
데이터:
# ex1. 반환 값 (0,1)
nums = [2, 7, 11, 15]
target = 9
# ex2. 반환 값 (-1, -1)
nums = [2, 7, 11, 15]
target = 10
def two_sum(nums, target):
"""
반환값 예: (0, 1) # nums[0] + nums[1] = 9
"""
# 여기에 코드를 작성하세요
return
# 예시 실행 (제출 시 주석 처리)
# print(two_sum(nums, target))
# %%
'''
nums1 = [2, 7, 11, 15]
target1 = 9
nums2 = [2, 7, 11, 15]
target2 = 10
nums3 = [7, 11, 15, 2]
target3 = 9
'''
def two_sum(nums, target):
result = ()
result2 = ()
for i in range(len(nums)):
for j in range(len(nums)):
if nums[i] + nums[j] == target:
result = (j, i)
else:
result2 = (-1, -1)
if len(result) >= 2:
return result
else:
return result2
# print(two_sum(nums1, target1)) # (0, 1)
# print(two_sum(nums2, target2)) # (-1, -1)
# print(two_sum(nums3, target3)) # (0, 3)
# %%
문제 7 : 이동 평균 구하기(슬라이딩 윈도우)
📌 요구 지식: 리스트, 반복문, 누적합(슬라이딩 윈도우)
배경:
시계열에서 일정 구간의 평균을 구해 노이즈를 줄입니다.
목표:
정수 리스트 data와 윈도우 크기 k가 주어질 때, 길이 k의 구간 평균 리스트를 반환하세요. (각 평균은 소수 둘째 자리 반올림)
데이터:
data = [10, 20, 30, 40, 50]
k = 3
def moving_average(data, k):
"""
반환값 예: [20.0, 30.0, 40.0]
"""
# 여기에 코드를 작성하세요
return
# 예시 실행 (제출 시 주석 처리)
# print(moving_average(data, k)) # [20.0, 30.0, 40.0]
# %%
def moving_average(data, k):
result = []
lendata = len(data)
if k > 0:
for i in range(0, lendata-k+1):
x = sum(data[:k]) / k
result.append(x)
data.pop(0)
return result
else:
result = []
return result
# %%
문제 8 : 숫자 구간 압축하기
📌 요구 지식: 리스트, 반복문, 조건문, 문자열 조합
문제배경
로그의 라인 번호나 주문 ID처럼 연속된 숫자 구간을 짧게 표현합니다.
목표
오름차순 정렬된 서로 다른 정수 리스트가 주어졌을 때, 연속 구간은 a-b, 단일 값은 a로 표현하여 ","로 연결한 문자열을 반환하세요.
예)
[1,2,3,5,7,8,9] → "1-3,5,7-9"
[1,3,5,7,9]-> "1,3,5,7,9"
제한사항
입력 리스트는 오름차순이며 중복이 없습니다.
데이터:
nums = [1, 2, 3, 5, 7, 8, 9]
def compress_ranges(nums):
"""
반환값 예: "1-3,5,7-9"
"""
# 여기에 코드를 작성하세요
return
# 예시 실행 (제출 시 주석 처리)
# print(compress_ranges(nums)) # "1-3,5,7-9"
# %%
def compress_ranges(nums):
leng = len(nums) # 7
result_list = []
no_duplication = set()
for i in range(leng):
if nums[i] in no_duplication:
continue
start_idx = i
end_idx = i
stop = True
for j in range(1, leng):
if i + j >= leng:
break
elif nums[i + j] == nums[i] + j:
end_idx = i + j
stop = False
else:
break
if stop:
result_list.append(str(nums[i]))
else:
result_list.append(f"{nums[start_idx]}-{nums[end_idx]}")
for k in range(start_idx, end_idx + 1):
no_duplication.add(nums[k])
result = ",".join(result_list)
return result
'Sparta > CODEKATA' 카테고리의 다른 글
| [250828] 스파르타코딩 본캠프 18일차 (2) (1) | 2025.08.28 |
|---|---|
| [250827] 스파르타코딩 본캠프 17일차 (3) | 2025.08.27 |
| [250825] 스파르타코딩 본캠프 15일차 (2) - 필수과제 (2) | 2025.08.25 |
| [250824] 파이썬 코테 01 (3) | 2025.08.24 |
| [250822] 스파르타코딩 본캠프 14일차 (2) (0) | 2025.08.22 |