[SQL] 프로그래머스 문제 풀이

BBANG-JUN·2020년 12월 17일
0

SQL

목록 보기
7/9
post-thumbnail

프로그래머스 문제풀이

level3

1> 없어진 기록 찾기

SELECT a.ANIMAL_ID, a.NAME
FROM ANIMAL_OUTS a LEFT OUTER JOIN ANIMAL_INS b ON a.ANIMAL_ID = b.ANIMAL_ID
WHERE b.ANIMAL_ID IS NULL;

[ 문제 ]
천재지변으로 인해 일부 데이터가 유실되었습니다. 입양을 간 기록은 있는데, 보호소에 들어온 기록이 없는 동물의 ID와 이름을 ID 순으로 조회하는 SQL문을 작성해주세요.

[ 이렇게 풀었습니다 ]
두 개의 테이블 중 데이터의 유무를 확인하는 방법은 LEFT JOIN을 사용했습니다.
모든 데이터가 나타나며 두 개의 테이블 중 없는 데이터는 빈 값인 즉, Null 상태입니다.
NULL의 유무를 따진다면 유실된 데이터가 무엇인지 확인할 수 있습니다.

2> 있었는데요 없었습니다.

SELECT a.ANIMAL_ID, a.NAME
FROM ANIMAL_INS AS a INNER JOIN ANIMAL_OUTS AS b ON a.ANIMAL_ID	= b.ANIMAL_ID
WHERE a.DATETIME > b.DATETIME
ORDER BY a.DATETIME

[ 문제 ]
관리자의 실수로 일부 동물의 입양일이 잘못 입력되었습니다. 보호 시작일보다 입양일이 더 빠른 동물의 아이디와 이름을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 시작일이 빠른 순으로 조회해야합니다.

[ 이렇게 풀었습니다 ]
조건으로 보호시작일보다 입양일이 더 빠른 경우를 찾고, 정렬기준을 보호 시작일 기준 오름차순으로 설정합니다. 두 테이블의 공통적인 부분을 적용하기 위해 INNER JOIN을 사용했습니다.

3> 오랜 기간 보호한 동물(1)

SELECT a.NAME, a.DATETIME
FROM ANIMAL_INS AS a LEFT JOIN ANIMAL_OUTS AS b ON a.ANIMAL_ID	= b.ANIMAL_ID
WHERE b.ANIMAL_ID is NULL
ORDER BY a.DATETIME
LIMIT 3

[ 문제 ]
아직 입양을 못 간 동물 중, 가장 오래 보호소에 있었던 동물 3마리의 이름과 보호 시작일을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 시작일 순으로 조회해야 합니다.

[ 이렇게 풀었습니다 ]
아직 입양을 못 간 동물이면 ANIMAL_OUTS 테이블에는 존재하지 않습니다.
LEFT JOIN을 이용하여 못 간 동물의 범위를 발견하고 정렬기준은 보호 시작일 순, 마지막으로 3개의 항목만 보여주기 위해 LIMIT을 걸어주었습니다.

4> 오랜 기간 보호한 동물(2)

SELECT a.ANIMAL_ID, a.NAME
FROM ANIMAL_INS AS a INNER JOIN ANIMAL_OUTS AS b ON a.ANIMAL_ID= b.ANIMAL_ID
ORDER BY a.DATETIME - b.DATETIME
LIMIT 2

[ 문제 ]
입양을 간 동물 중, 보호 기간이 가장 길었던 동물 두 마리의 아이디와 이름을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 기간이 긴 순으로 조회해야 합니다.

[ 이렇게 풀었습니다 ]
입양을 간 동물들을 찾기에, INNER JOIN으로 ANIMAL_OUTS에 데이터가 존재하는 것만 가져왔습니다.
정렬기준을 보호기간 - 입양기간으로 정해 가장 길었던 동물들 순으로 정렬되게 합니다.
마지막으로 두 마리만 정보를 추출해야하므로 LIMIT을 적용했습니다.

level4

1> 우유와 요거트가 담긴 장바구니

SELECT DISTINCT A.CART_ID
FROM (SELECT * FROM CART_PRODUCTS WHERE NAME = 'Yogurt') AS A,
     (SELECT * FROM CART_PRODUCTS WHERE NAME = 'Milk') AS B
WHERE A.CART_ID = B.CART_ID
ORDER BY A.ID

[ 문제 ]
데이터 분석 팀에서는 우유(Milk)와 요거트(Yogurt)를 동시에 구입한 장바구니가 있는지 알아보려 합니다. 우유와 요거트를 동시에 구입한 장바구니의 아이디를 조회하는 SQL 문을 작성해주세요. 이때 결과는 장바구니의 아이디 순으로 나와야 합니다.

[ 이렇게 풀었습니다 ]
요거트만 구매한 테이블과, 밀크를 구매한 테이블에 둘 다 존재하게 된다면, 동시에 구입한 테이블이 형성됩니다. ID 순으로 정렬기준을 정해주고 중복을 제거하기에 DISTINCT를 추가해주었습니다.

2> 보호소에서 중성화한 동물

select a.ANIMAL_ID, a.ANIMAL_TYPE, a.NAME 
from ANIMAL_INS a inner join ANIMAL_OUTS b on a.ANIMAL_ID = b.ANIMAL_ID
where a.SEX_UPON_INTAKE in ('Intact Male', 'Intact Female')
and b.SEX_UPON_OUTCOME  in ('Spayed Female', 'Neutered Male')
ORDER BY a.ANIMAL_ID

[ 문제 ]
보호소에서 중성화 수술을 거친 동물 정보를 알아보려 합니다. 보호소에 들어올 당시에는 중성화되지 않았지만, 보호소를 나갈 당시에는 중성화된 동물의 아이디와 생물 종, 이름을 조회하는 아이디 순으로 조회하는 SQL 문을 작성해주세요.

[ 이렇게 풀었습니다 ]
보호소 테이블과 입양 테이블에 동시에 존재하는 동물들을 INNER JOIN으로 파악합니다.
이후, 보호소 테이블의 조건(Intact한 상태 수, 암)과 입양소 테이블의 조건(수는 Spayed, 암은 Neutered)을 동시에 걸어주면 해당 결과가 나타나게 됩니다.
아이디 순이므로 정렬기준을 정해주었습니다.

3> 입양 시각 구하기(2)

SET @hour := -1;

SELECT (@hour := @hour + 1) as HOUR,
        (
            SELECT COUNT(*) 
            FROM ANIMAL_OUTS 
            WHERE HOUR(DATETIME) = @hour
        ) as COUNT
FROM ANIMAL_OUTS
WHERE @hour < 23

[ 문제 ]
보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는 시간대 순으로 정렬해야 합니다.

[ 이렇게 풀었습니다 ]
개인적으로 가장 어려웠던 문제입니다.
My SQL에서 변수를 선언해주기 위해서는 SET @'변수이름'을 설정할 수 있습니다.

hour 라는 변수를 -1 값으로 설정해준 이유는, 반복문으로 0부터 23시를 표현하기 위해서입니다.
증감 및 조건에 의해서 반복되는 것으로 총 24개의 행이 생성됩니다.

해당 시간을 기준으로 DATETIME의 시간만 추출하기 위해 HOUR()을 사용해주었습니다.
입양 건수를 측정하여 COUNT 결과로 나타내주었습니다.

profile
🔥 머릿속으로 생각하지만 말고, 행동으로 보여줘

0개의 댓글