본문 바로가기
DA/코드카타

0605 코드카타 - SQL(31~35), 파이썬(13~15)

by chysh 2025. 6. 5.

[SQL]

31. 오랜기간 보호한 동물(1)

(ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다.)

(ANIMAL_OUTS 테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME는 각각 동물의 아이디, 생물 종, 입양일, 이름, 성별 및 중성화 여부를 나타냅니다. ANIMAL_OUTS 테이블의 ANIMAL_ID ANIMAL_INS ANIMAL_ID의 외래 키입니다.)

-아직 입양을 못 간 동물 중, 가장 오래 보호소에 있었던 동물 3마리의 이름과 보호시작일 조회, 보호시작일 순으로 조회

 

-- 코드를 입력하세요
SELECT i.name, i.datetime
FROM animal_ins i left join animal_outs o
on i.animal_id=o.animal_id
WHERE o.animal_id is null
order by 2
limit 3

 

--다른 풀이

SELECT
    name,
    datetime
FROM animal_ins a
WHERE NOT EXISTS (
    SELECT 1 
    FROM animal_outs b 
    WHERE a.animal_id = b.animal_id  -- 입양 기록 존재 여부만 체크
)
ORDER BY datetime ASC  -- 보호 시작일 오름차순 정렬 (가장 오래된 순)
LIMIT 3;   

*not exists 잘 생각이 안나서 그냥 left join으로 풀었다.. 문법 익혀두기

 

 

32. 카테고리별 도서 판매량 집계


-2022년 1월의 카테고리 별 도서 판매량 합산하고, 카테고리(CATEGORY), 총 판매량(TOTAL_SALES) 리스트 출력.

카테고리명 기준으로 오름차순 정렬

 

 

-- 코드를 입력하세요
SELECT a.category, sum(b.sales) as TOTAL_SALES
from book a join book_sales b on a.book_id=b.book_id
where b.sales_date>='2022-01-01'and b.sales_date<'2022-02-01'
group by 1 
order by 1

 

 

33. 상품 별 오프라인 매출 구하기

-product 테이블과 offline_sale 테이블에서 상품코드 별 매출액(판매가*판매량) 합계를 출력하는 sql문 작성.

결과는 매출액 기준으로 내림차순 정렬, 매출액 같으면 상품코드 기준으로 오름차순 정렬

 

-- 코드를 입력하세요
select p.product_code, p.price*sum(s.sales_amount)as SALES
from product p inner join offline_sale s on p.product_id=s.product_id
group by p.product_code
order by 2 desc, 1 asc

 

--다른 풀이

*좀 더 직관적으로

sum(p.price*s.sales_amount) as sales

 

 

34.있었는데요 없었습니다

(31번 테이블 참고)

-일부 동물의 입양일이 잘못 입력됨. 보호 시작일보다 입양일이 더 빠른 동물의 아이디와 이름 조회. 보호시작일이 빠른순 조회.

 

-- 코드를 입력하세요
select i.animal_id, i.name
from animal_ins i join animal_outs o on i.animal_id=o.animal_id
where o.datetime<i.datetime 
order by i.datetime

 

*집계함수 사용하는게 아니라, 그냥 행을 출력하는거라서 group by 필요 없음.

 

 

35.오랜기간 보호한 동물(2)

(31번 테이블 참고)

-입양간 동물 중, 보호기간이 가장 길었던 동물 두마리의 아이디와 이름 조회, 보호기간이 긴 순으로 조회

 

 

-- 코드를 입력하세요
select o.ANIMAL_ID, o.NAME
from animal_ins i join animal_outs o on i.animal_id=o.animal_id 
order by (o.datetime-i.datetime) desc
limit 2

 

*이런 경우 inner join사용하는게 나음(입양기록이 확실한 동물만 조회)

*datediff(큰날짜, 작은날짜) - 날짜 계산은 이렇게 정확히 하는게 나음

 

--다른 방법

SELECT
    A.ANIMAL_ID,
    A.NAME
FROM ANIMAL_INS A
LEFT JOIN ANIMAL_OUTS B
ON A.ANIMAL_ID = B.ANIMAL_ID
WHERE B.ANIMAL_ID IS NOT NULL
ORDER BY TIMESTAMPDIFF(DAY, A.DATETIME, B.DATETIME) DESC
LIMIT 2

*시간의 차 : TIMESTAMPDIFF(DAY, I.DATETIME, O.DATETIME) DESC


[파이썬]

13. 자릿수 더하기

-자연수 N의 각 자릿수의 합을 구해서 return

 

--코드

def solution(n):
    num_list = list(str(n))
    answer = 0
    for i in range(0, len(num_list)):
        num=int(num_list[i])
        answer += num
    return answer

 

# 겨우 풀었다.. 일단 list에 차례로 담겼는지 확인하고,

논리적인 절차대로 진행하니까 됐음.

 

--다른 풀이

1) 진짜 이게 뭔..?*재귀함수

if number < 10:
        return number

    return number%10 + sum_digit(number//10)

 

2) 리스트 컴프리헨션

def sum_digit(number):
    return sum([int(i) for i in str(number)])
print("결과 : {}".format(sum_digit(123)));

 

3) map

def sum_digit(number):
    return sum(map(int, str(number)))

 

 

14. 약수의 합

-정수 n의 약수를 모두 더한 값 리턴

 

--코드

def solution(n):
    num=0
    for i in range(1, n+1):
        if n%i ==0:
            num+= i
    return num
       

 

--다른 코드

1) 리스트 컴프리헨션

return sum([i for i in range(1,num+1) if num%i==0])

 

 

15.나머지가 1이 되는 수 찾기

-자연수 n이 매개변수로 주어짐. n을 x로 나눈 나머지가 1이 되도록 하는 가장 작은 자연수 x를 리턴

(3<=n<=1000000)

 

--코드

def solution(n):
    for x in range(2, n+1):
        if n%x ==1:
            return x