2025.03.10 본_캠프 14일차

민동·2025년 3월 10일
1

본캠프

목록 보기
16/74
post-thumbnail

1. 81번 ~ 85번 SQL 정리


81번: 길이가 15 초과하는 트윗 찾기

문제 설명

Tweets 테이블에서 content 길이가 15 초과하는 tweet_id 찾기
결과는 임의의 순서로 출력

정답

SELECT tweet_id 
FROM Tweets
WHERE LENGTH(content) > 15;

쿼리 설명

  1. LENGTH(content) > 15
    → content(트윗 내용)의 길이가 15 초과하는 경우만 필터링
  2. tweet_id를 조회하여 반환

82번: 직원의 고유 ID 찾기

문제 설명

  • Employees 테이블에서 직원들의 name 조회
  • EmployeeUNI 테이블에서 직원의 unique_id 조회
  • 고유 ID가 없는 경우 NULL로 표시

정답

SELECT unique_id, name
FROM Employees E LEFT JOIN EmployeeUNI U ON U.id = E.id;

쿼리 설명

  1. LEFT JOIN을 사용하여 Employees 테이블과 EmployeeUNI 테이블 결합
  2. U.id = E.id 를 기준으로 직원의 고유 ID 매칭
  3. unique_id가 없는 경우 NULL 반환

83번: 제품의 연도별 가격 조회

문제 설명

  • Sales 테이블에서 판매된 제품의 연도별 가격 조회
  • Product 테이블과 조인하여 제품 이름(product_name)을 함께 출력

정답

SELECT p.product_name, s.year, s.price
FROM Sales s JOIN Product p ON s.product_id = p.product_id;

쿼리 설명

  1. JOIN을 사용하여 Sales와 Product 테이블 결합
  2. p.product_id = s.product_id 로 제품명 매칭
  3. product_name, year, price를 조회하여 결과 반환

84번: 거래 없는 방문 고객 찾기

문제 설명

  • Visits 테이블에는 방문 정보 저장
  • Transactions 테이블에는 거래 정보 저장
  • 거래를 하지 않은 고객(customer_id)과 거래 없는 방문 횟수(count_no_trans)를 조회

정답

SELECT V.customer_id, COUNT(1) count_no_trans 
FROM Visits V LEFT JOIN Transactions T ON V.visit_id = T.visit_id
WHERE T.transaction_id IS NULL
GROUP BY V.customer_id;

쿼리 설명

  1. LEFT JOIN을 사용하여 Visits와 Transactions 테이블 결합
  2. T.transaction_id IS NULL
    → 거래 기록이 없는 방문 데이터만 필터링
  3. COUNT(1)
    → 거래 없는 방문 횟수를 세어 count_no_trans로 출력

cf) 코드카타 80번 문제를 보니 문득 LAG함수를 사용해 적용해 보고 싶었다. 물론 그냥 DATEDIFF함수를 사용하면 쉽게 풀리겠지만 쉬운문제에 LAG함수를 적용해봐야 나중에 잘 쓸 수 있지 않을까라는 생각이 들었다.

  • LAG()란?
    LAG() 한수는 현재 행의 이전 행 값을 가져오는 윈도우 함수이다. 즉, 이전 행의 데이터를 참조하여 비교하거나 계산할때 유용하다.

    LAG(컬럼명, 이동할 행 수, 기본값) OVER (PARTITION BY 그룹컬럼 ORDER BY 정렬컬럼)

Weather table(원본 테이블)

idrecordDatetemperature
12015-01-0110
22015-01-0225
32015-01-0320
42015-01-0430

이전 날짜와 온도를 비교하기 위해 LAG()함수를 사용하기

idrecordDatetemperatureprev_temp
12015-01-0110null
22015-01-022510
32015-01-032025
42015-01-043020

cf)
LAG() vs LEAD() 차이

함수설명
LAG(컬럼, N, 기본값)현재 행의 N행 이전 값 가져옴
LEAD(컬럼, N, 기본값)현재 행의 N행 이후 값 가져옴

85번: 전날보다 기온이 높은 날짜 찾기

문제 설명

  • Weather 테이블에서 전날보다 기온이 높은 날짜의 id 조회
  • 전날의 기온을 비교하기 위해 윈도우 함수 사용

정답

SELECT id
FROM
(
    SELECT id, recordDate, temperature,
           LAG(temperature, 1, NULL) OVER (ORDER BY recordDate) prev_temp
    FROM Weather
) a
WHERE temperature > prev_temp;

쿼리 설명

  1. LAG(temperature, 1, NULL) OVER (ORDER BY recordDate)
    • 이전 날짜의 기온(prev_temp)을 가져옴
    • 첫 번째 행은 이전 데이터가 없으므로 NULL 반환
  2. WHERE temperature > prev_temp
    • 현재 온도가 전날보다 높은 경우만 필터링
  3. 결과적으로 기온이 오른 날짜의 id만 출력

정리

이번 문제들에서 배운 핵심 개념

  • LENGTH(): 문자열 길이 계산
  • LEFT JOIN: 특정 테이블에 대응하는 데이터가 없어도 결과 포함
  • LAG(): 이전 행 데이터 가져오기
  • IS NULL: NULL 값 필터링

2.파이썬 알고리즘 문제 풀이 (21~25번)


21번 - 하샤드 수

문제 설명
양의 정수 x가 하샤드 수가 되려면 x의 자릿수의 합으로 x가 나누어 떨어져야 한다.
즉, x의 각 자릿수를 더한 값으로 x를 나누었을 때 나누어 떨어지면 하샤드 수이다.

정답 코드

def solution(x):
    answer = sum(int(i) for i in str(x))
    answer = x % answer == 0
    return answer

코드 설명
sum(int(i) for i in str(x))를 통해 x의 각 자릿수를 더한다.
그 후 x가 그 값으로 나누어 떨어지는지 확인하여 결과를 반환한다.


22번 - 두 정수 사이의 합

문제 설명
두 정수 a, b가 주어졌을 때 ab 사이에 속한 모든 정수의 합을 반환하는 함수이다.

정답 코드

def solution(a, b):
    answer = (abs(a-b)+1) * (a+b)//2
    return answer

코드 설명
abs(a-b)+1을 통해 두 숫자 사이의 숫자 개수를 구하고, (a+b)//2를 사용하여 등차수열의 합 공식으로 값을 계산한다.

cf)
(a+b)//2 에서 왜 (a+b)/2를 안 쓰는가?
//와 /의 차이

연산자설명예제
/실수(소수) 나눗셈5 / 2 = 2.5
//정수 나눗셈 (소수점 버림)5 // 2 = 2
  • /는 나누기 연산을 하고 항상 실수(float)를 반환
  • //는 나누기 연산 후 소수점 이하를 버리고 정수(int)만 반환

문제에서 두 정수 사이의 모든 숫자의 합을 구해야 하므로, 결과도 정수여야 하는거 같다.
즉, 실수(/)가 아닌 정수(//)를 사용해야 문제가 발생하지 않음


23번 - 콜라츠 추측

문제 설명
주어진 수 num이 1이 될 때까지 다음 규칙을 반복한다.
1. num이 짝수라면 2로 나눈다.
2. num이 홀수라면 3을 곱하고 1을 더한다.
3. 500번 반복해도 1이 되지 않으면 -1을 반환한다.

정답 코드

def solution(num):
    answer = 0
    
    while num != 1 and answer < 500:
        if num % 2 == 0:
            num //= 2
        else:
            num = num * 3 + 1
        answer += 1
    
    return answer if num == 1 else -1

코드 설명
while num != 1 and answer < 500:을 통해 num이 1이 되거나 500번 반복할 때까지 실행한다.
if num % 2 == 0:이면 짝수이므로 // 2를 실행하고,
그렇지 않으면 num * 3 + 1을 수행하여 1이 될 때까지 반복한다.
반복 횟수를 answer 변수에 저장하고 500번 초과 시 -1을 반환한다.

cf) answer += 1 을 왜 하는가?
answer 는 num이 1이 될때까지 몇 번 연산했는가를 저장하는 변수이다. 매번 num을 변경할 때마다 answer += 1을 수행하여 반복 횟수를 증가한다.

콜라츠 추축 문제에서는 1이 될때까지 몇 번 반복했는지 알아야 하기 때문에 answer += 1을 사용


24번 - 서울에서 김서방 찾기

문제 설명
문자열 배열 seoul에서 "Kim"의 위치를 찾아 "김서방은 x에 있다" 형태의 문자열을 반환하는 함수이다.

정답 코드

def solution(seoul):
    answer = f"김서방은 {seoul.index('Kim')}에 있다"
    return answer

코드 설명
seoul.index("Kim")을 사용하여 "Kim"이 있는 인덱스 위치를 찾는다.
찾은 인덱스를 f-문자열을 활용하여 "김서방은 x에 있다" 형식으로 출력한다.


25번 - 나누어 떨어지는 숫자 배열

문제 설명
배열 arr의 각 원소 중 divisor로 나누어 떨어지는 값만 포함하여 오름차순 정렬한 배열을 반환하는 함수이다.
만약 나누어 떨어지는 값이 없다면 [-1]을 반환한다.

정답 코드

def solution(arr, divisor):
    answer = []
    for num in arr:
        if num % divisor == 0:
            answer.append(num)
    if not answer:
        answer.append(-1)   
    answer.sort()
    return answer

코드 설명
if num % divisor == 0:을 사용하여 divisor로 나누어 떨어지는 숫자만 answer 리스트에 추가한다.
if not answer:을 활용하여 나누어 떨어지는 숫자가 없을 경우 [-1]을 추가한다.
마지막으로 answer.sort()를 통해 오름차순 정렬을 수행한 후 반환한다.

cf)

  • answer.sort()
    return answer이 정답이고

  • return answer.sort()이 오답인 이유?

answer.sort()는 리스트를 정렬하지만, 정렬된 리스트를 반환하지 않음
answer.sort()는 리스트를 직접 변경하고,None을 반환함
따라서 return answer.sort()를 실행하면 None이 반환됨


3. python 개인 과제

문제 1: 숫자 리스트의 평균 계산

문제 설명

전자 상거래 플랫폼에서 고객의 평균 주문을 계산하기 위해, 숫자 리스트의 평균을 구하는 함수를 작성하세요.

작성한 코드

import numpy as np

def calculate_avg(numbers):
    return np.mean(numbers)

numbers = [10, 20, 30, 40, 50]
total_avg = calculate_avg(numbers)

print("숫자들의 평균:", total_avg)

코드 설명

  1. numpymean() 함수를 사용하여 숫자 리스트의 평균을 계산함.
  2. calculate_avg() 함수가 리스트를 받아 평균을 반환함.
  3. 결과를 total_avg에 저장하고 출력함.

문제 2: 일교차 계산

문제 설명

기상청에서는 하루 동안 가장 높았던 기온과 가장 낮았던 기온을 확인하여 일교차를 보고합니다. 주어진 기온 리스트에서 일교차를 계산하는 함수를 작성하세요.

작성한 코드

numbers = [10, 20, 30, 40, 50]

def calculate_diff_temperature(numbers):
    diff_temp = max(numbers) - min(numbers)
    return diff_temp

diff_temp = calculate_diff_temperature(numbers)
print("일교차:", diff_temp)

코드 설명

  1. max()min()을 사용하여 최고 기온과 최저 기온을 찾음.
  2. 두 값의 차이를 계산하여 일교차를 반환함.
  3. 결과를 diff_temp에 저장하고 출력함.

문제 3: 가장 많이 판매된 제품 찾기

문제 설명

한 소매점에서 한 달 동안 가장 많이 판매된 제품의 이름과 수량을 찾는 함수를 작성하세요.

작성한 코드

def find_top_seller(sales_data):
    max_sales = max(sales_data.values())
    for top_product, sales in sales_data.items():
        if sales == max_sales:
            return top_product, max_sales    

# 테스트
sales_data = {"apple": 50, "orange": 2, "banana": 30}
print("가장 많이 판매된 제품과 수량:", find_top_seller(sales_data))

코드 설명

  1. max()를 사용하여 판매량이 가장 높은 값을 max_sales에 저장.
  2. for 루프를 사용해 딕셔너리를 순회하면서, max_sales와 같은 값을 찾으면 반환함.

문제 4: 사칙연산 계산기 구현

문제 설명

두 숫자와 연산자를 입력받아, 해당 연산을 수행하는 계산기 함수를 작성하세요.
나누기 연산("/")의 경우, 0으로 나누는 경우 "Cannot divide by zero"를 반환해야 합니다.

작성한 코드

def simple_calculator(num1, num2, operator):
    try:
        if operator == '+':
            return num1 + num2
        elif operator == '-':
            return num1 - num2
        elif operator == '*':
            return num1 * num2
        elif operator == '/':
            return num1 / num2
        else:
            return 0
    except ZeroDivisionError:
        return "Cannot divide by zero"

# 테스트
print(simple_calculator(10, 5, '+'))  # 출력: 15
print(simple_calculator(10, 5, '-'))  # 출력: 5
print(simple_calculator(10, 5, '*'))  # 출력: 50
print(simple_calculator(10, 0, '/'))  # 출력: 'Cannot divide by zero'

코드 설명

  1. if-elif 문을 사용하여 사칙연산을 수행.
  2. 나누기 연산("/")에서 num2 == 0일 경우, ZeroDivisionError 예외 처리.
  3. 지원하지 않는 연산자가 입력되면 0을 반환.

cf) try,except 처음 사용해본거 같다.
예외(exception)란 코드를 실행하는 중에 발생한 에러를 뜻한다.

try-except는 파이썬에서 오류(예외)를 처리하는 기능으로, 프로그램 실행중 예상치 못한 오류가 발생해도 프로그램이 멈추지 않도록 도와주는 기능이다.

try-except 핵심 정리

기능설명
try오류가 발생할 수 있는 코드를 실행
except예외타입
except Exception as e모든 오류를 처리하고 오류 메시
  • try-except를 사용하면?
    - 예외가 발생해도 프로그램이 멈추지 않고 정상 실행됨
    - 예외 발생 시 원하는 메시지를 출력 가능
    - 다양한 오류를 구체적으로 처리 가능

여담) 두산이 드디어 시범 경기에서 삼성을 이겼다^ㅁ^

profile
아자아자

0개의 댓글