단계 JOIN
1. 없어진 기록 찾기
SELECT O.ANIMAL_ID, O.NAME
FROM ANIMAL_OUTS O LEFT OUTER JOIN ANIMAL_INS I ON
O.ANIMAL_ID = I.ANIMAL_ID
WHERE I.ANIMAL_ID IS NULL
ORDER BY O.ANIMAL_ID;
입양 기록은 그대로 있으니까 일단 입양기록테이블을 왼쪽에 두고 보호소 기록 테이블과 Left Outer Join을 한다.
입양 기록 A, B, E | 보호소 기록 B, C, E
LEFT OUTER JOIN = (A, null), (B, B), (E,E)가 남게 된다. 잃어버린 기록은 보호소 기록에서 null로 조인된 행이다.
따라서 조건절에 I.ANIMAL_ID IS NULL 을 작성했다.
2. 있었는데요 없었습니다.
SELECT I.ANIMAL_ID, I.NAME -- ID와 NAME 정보 출력
FROM ANIMAL_INS I INNER JOIN ANIMAL_OUTS O ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE I.DATETIME > O.DATETIME -- 날짜 비교
ORDER BY I.DATETIME;
이 문제는 입양일이 보호시작일보다 빠른 동물의 ID, 이름을 조회하는 문제이다.
INS테이블과 OUTS 테이블 모두 존재하는 것을 조회해야하기 떄문에 테이블의 교집합이 필요했다. 따라서 INNER JOIN을 통해 조인해주었고 조건절에서 날짜비교를 해주었다.
3. 오랜 기간 보호한 동물(1)
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 I.DATETIME
LIMIT 3; -- 상위에서 3개만 출력
3. 보호소에서 중성화한 동물
SELECT I.ANIMAL_ID, I.ANIMAL_TYPE, I.NAME
FROM ANIMAL_INS I INNER JOIN ANIMAL_OUTS O ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE I.SEX_UPON_INTAKE != O.SEX_UPON_OUTCOME;
보호소에서는 중성화를 하지 않았고 입양 시 중성화를 한 동물을 찾는 문제이다.
여기서 3가지 케이스로 나뉘는데
1. 중성화하지않음 -> 중성화 ***
2. 중성화하지않음 -> 중성화하지않음
3. 중성화 -> 중성화
이 3가지 케이스 중 우리가 찾을 문제는 INS테이블의 SEX_UPON_INTAKE와 OUTS테이블의 SEX_UPON_OUTCOME 값이 같지 않을 때, 중성화를 한 동물이라고 볼 수 있다.
따라서 INS테이블과 OUTS테이블을 조인한 후, 조건절을 이용해 문제에 대한 답을 찾아주었다.
단계 String, Date
1. 루시와 엘라 찾기
SELECT ANIMAL_ID, NAME, SEX_UPON_INTAKE
FROM ANIMAL_INS
WHERE NAME IN ('Lucy', 'Ella', 'Pickle', 'Rogan', 'Sabrina', 'Mitty')
ORDER BY ANIMAL_ID;
IN을 사용해서 특정 값만 조회가 가능하다. 또한 특정값이 아닐 경우를 찾고 싶다면 NOT IN('')을 사용할 수 있다.
2. 이름에 el이 들어가는 동물 찾기
SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
WHERE NAME LIKE '%el%' and ANIMAL_TYPE = 'Dog'
ORDER BY NAME;
특정 문자열이 포함된 값을 찾으려면 LIKE를 사용하면 된다. LIKE에 대해 정리해보면,
1. el로 끝나는 단어 : LIKE '%el'
2. el로 시작하는 단어 : LIKE 'el%'
3. el이 포함된 단어 : LIKE '%el%'
또한 MySQL은 대소문자를 구별하지 않는다.
3. 중성화 여부 파악하기
SELECT ANIMAL_ID, NAME,
CASE WHEN SEX_UPON_INTAKE LIKE '%Neutered%' or SEX_UPON_INTAKE LIKE '%Spayed%'
then 'O'
ELSE 'X'
END AS '중성화'
FROM ANIMAL_INS;
쉽게 풀어서 자신있게 실행했는데 계속 오류가 났다. 그 이유는 CASE 절에 WHEN을 안쓴 것....
급하게 풀지말고 기초적인 거라도 꼼꼼히 봐야한다는 걸 늘 명심하자!
SELECT ANIMAL_ID, NAME,
IF(SEX_UPON_INTAKE LIKE '%Neutered%' or SEX_UPON_INTAKE LIKE '%Spayed%', 'O', 'X') AS '중성화'
FROM ANIMAL_INS;
IF절로도 풀어보았다!
4. 오랜 기간 보호한 동물(2)
SELECT I.ANIMAL_ID, I.NAME
FROM ANIMAL_INS I INNER JOIN ANIMAL_OUTS O ON I.ANIMAL_ID = O.ANIMAL_ID
ORDER BY DATEDIFF('O.DATETIME', 'I.DATETIME') DESC
LIMIT 2;
입양간 동물의 보호소 기록이 필요하기 떄문에 먼저 두 테이블을 조인시켜주었따. 그 다음 입양날-보호소날 차이를 계산하는 DATEDIFF함수로 정렬을 해주었고, 숫자가 큰게 오래 보호소에 있었다는 의미니까 내림차순으로 정렬해주었다.
5. DATETIME에서 DATE로 형 변환
SELECT ANIMAL_ID, NAME, DATE_FORMAT(DATETIME, '%Y-%m-%d') AS '날짜'
FROM ANIMAL_INS
ORDER BY ANIMAL_ID;
이전 문제를 풀때 시간/날짜 관련 함수를 잘 정리해놔서 손 쉽게 풀 수 있었다.
이렇게 프로그래머스 SQL 고득점 KIT를 풀어보았다. SQL 코딩테스트를 보는 기업에도 지원하고 싶기 때문에 먼저 가볍게 풀어봤는데 재밌다~! 까먹은 여러 문법들도 있으니 다시 한번 정리하면서 복습해야겠다.
'코딩테스트 준비 > SQL 코테' 카테고리의 다른 글
MySQL 문법 정리 (0) | 2022.03.03 |
---|---|
[프로그래머스 SQL 고득점 KIT] 문제 풀이 (MySQL) (0) | 2022.03.02 |
댓글