JOIN 문제들은 테이블 2개를 합쳐서 풀어야 하는만큼 문제를 이해하는데 더 많은 시간이 걸렸다.
- 없어진 기록 찾기
ANIMAL_INS(as I) : 보호소에 들어온 기록, ANIMAL_OUTS(as O) : (보호소에서) 입양 간 기록
SELECT O.ANIMAL_ID, O.NAME
FROM ANIMAL_INS I RIGHT JOIN ANIMAL_OUTS O ON I.ANIMAL_ID = O.ANIMAL_ID
# 입양을 간 기록을 기준으로 두 테이블 조인
WHERE I.ANIMAL_ID IS NULL # 입양을 갔지만 보호소에 기록이 없는 동물의 ID
# where 절이 없으면 입양을 가서 보호소에 들어온 동물, 입양을 갔지만 보호소에 들어오지 않은 동물에 대한 모든 기록 존재
ORDER BY O.ANIMAL_ID;
1. 두 테이블을 어떤 종류의 조인을 할지
예시를 보면, 테이블 I와 테이블 O에 동일하게 이름 Gia가 있는데 출력되어야 하는 결과는 O 테이블의 Allie와 Spice 이므로 O 테이블쪽으로 조인을 걸어야 한다.
2. 문제의 핵심은 '입양을 간 기록은 있는데 보호소에 들어온 기록이 없는 동물' 이다.
이해를 위해 전체 컬럼을 가져와 살펴보면, ANIMAL_ID ~ SEX_UPOP_INTAKE는 I 테이블, ANIMAL_ID~SEX_UPOP_OUTCOME은 O 테이블이다. 즉, 입양을 보낸 테이블(O)에는 동물의 정보가 기록되어 있는데, 정작 보호소에 들어온 동물의 정보(I)가 일부 비어있는 것을 볼 수 있다. 따라서 I 테이블에서 동물의 ID가 비어 있다는 것을 조건으로 걸면 '입양을 간 기록은 있는데 보호소에 들어온 기록이 없는 동물'을 파악할 수 있다.
3. 테이블 I에는 동물의 ID를 비롯한 보호소 정보가 비어 있기 때문에 테이블 O에서 ID랑 이름 가져오기
- 있었는데요 없었습니다
관리자의 실수로 일부 동물의 입양일이 잘못 입력되었습니다. 보호 시작일보다 입양일이 더 빠른 동물의 아이디와 이름을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 시작일이 빠른 순으로 조회해야합니다.
# 보호 시작일(I) > 입양일(O)
SELECT O.ANIMAL_ID, O.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;
1. 두 테이블을 어떤 종류의 조인을 할지
예시를 보면, 어떤 테이블을 기준으로 조인하기보다는 동물의 ID가 동일한 동물의 DATETIME를 비교해야 한다.
2. 문제의 핵심은 '보호 시작일보다 입양일이 더 빠른' 이다.
날짜 ASC 예전부터 최신날짜까지 정렬, DESC 최신날짜부터 예전으로 정렬. (헷갈리지 않게 주의!!)
3. 이너 조인은 교집합만 추출하기 때문에 O 테이블이든 I 테이블이든 ID와 이름을 가져와도 크게 상관없는 듯 하지만, 문제를 잘 읽어보고 어떤 테이블에서 정보를 가져올지 고민하자.
- 오랜 기간 보호한 동물(1)
아직 입양을 못 간 동물 중, 가장 오래 보호소에 있었던 동물 3마리의 이름과 보호 시작일을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 시작일 순으로 조회해야 합니다.
# 보호 시작일(I), 입양일(O)
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;
1. 두 테이블을 어떤 종류의 조인을 할지
우선 Ariel과 Rosie가 두 테이블에 존재한다는 것은 보호소에 있다가 입양을 갔다는 의미이다.
문제에서 가장 오래 보호소에 있었던 동물의 정보(I), 예시 출력결과를 보면 I 테이블의 동물들이 출력되어서 테이블 I 쪽으로 조인을 걸어야 한다.
2. 문제의 핵심은 '아직 입양을 못 간 동물' 이다.
즉, 입양에 대한 정보가 기록된 테이블 O에서 동물 ID가 비어있다는 것을 조건으로 걸면 된다.
3. 테이블 O에는 동물의 ID를 비롯한 입양정보가 비어 있기 때문에 테이블 I에서 ID랑 이름이랑 보호 시작일 가져오기
그리고 Limit는 Order by 절에 작성하는거 잊지 말기!
- 보호소에서 중성화한 동물
보호소에서 중성화 수술을 거친 동물 정보를 알아보려 합니다. 보호소에 들어올 당시에는 중성화1되지 않았지만, 보호소를 나갈 당시에는 중성화된 동물의 아이디와 생물 종, 이름을 조회하는 아이디 순으로 조회하는 SQL 문을 작성해주세요.
# 보호 시작일(I), 입양일(O)
# 중성화를 거치지 않은 동물은 Intact(I - 보호소 들어올 때), 중성화를 거친 동물은 Spayed 또는 Neutered(O - 보호소 나갈 때)
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 LIKE 'Intact%'
AND (O.SEX_UPON_OUTCOME LIKE 'Spayed%' OR O.SEX_UPON_OUTCOME LIKE 'Neutered%')
ORDER BY I.ANIMAL_ID
1. 두 테이블을 어떤 종류의 조인을 할지
두 번째 문제와 동일하게 두 테이블 간에 동물의 중성화 여부를 비교해야 하기 때문에 교집합만 추출하는 이너 조인
2. 문제의 핵심은 '보호소에 들어올 당시에는 중성화되지 않았지만, 보호소를 나갈 당시에는 중성화된 동물' 이다.
즉, 두 테이블 간 동물의 ID가 동일한 동물 중, 보호소 기록이 있는 테이블(I)에서는 중성화 여부가 Intact -> 입양 기록이 있는 테이블(O)에서는 중성화 여부가 Spayed 혹은 Neutered 여야 한다는 것이다. 따라서 LIKE 문을 사용해 해당 문자가 있는지 판단했다.
'DB > SQL' 카테고리의 다른 글
[Programmers] GROUP BY (0) | 2023.01.16 |
---|---|
[programmers] SELECT (0) | 2023.01.10 |
[programmers] IS NULL 문제 풀기 (0) | 2022.09.15 |
[programmers] GROUP BY 문제 풀기 (0) | 2022.08.24 |
[programmers] SUM, MAX, MIN (0) | 2022.08.18 |