있었는데요 없었습니다
JOIN
있었는데요 없었습니다
문제 설명
다음은 동물 보호소에서 관리하는 정보를 담은 ANIMAL_INS 테이블과 동물 보호소에서 입양 보낸 동물의 정보를 담은 ANIMAL_OUTS 테이블입니다.
ANIMAL_INS 테이블
Column name | Type | Nullable | Description |
---|---|---|---|
ANIMAL_ID | VARCHAR(N) | FALSE | 동물 ID |
ANIMAL_TYPE | VARCHAR(N) | FALSE | 생물 종 |
DATETIME | DATETIME | FALSE | 보호 시작일 |
INTAKE_CONDITION | VARCHAR(N) | FALSE | 보호 시작 시 상태 |
NAME | VARCHAR(N) | TRUE | 이름 |
SEX_UPON_INTAKE | VARCHAR(N) | FALSE | 성별 및 중성화 여부 |
ANIMAL_OUTS 테이블
Column name | Type | Nullable | Description |
---|---|---|---|
ANIMAL_ID | VARCHAR(N) | FALSE | 동물 ID |
ANIMAL_TYPE | VARCHAR(N) | FALSE | 생물 종 |
DATETIME | DATETIME | FALSE | 입양일 |
NAME | VARCHAR(N) | TRUE | 이름 |
SEX_UPON_OUTCOME | VARCHAR(N) | FALSE | 성별 및 중성화 여부 |
ANIMAL_OUTS 테이블의 ANIMAL_ID
는 ANIMAL_INS의 ANIMAL_ID
의 외래 키입니다.
문제
관리자의 실수로 일부 동물의 입양일이 잘못 입력되었습니다. 보호 시작일보다 입양일이 더 빠른 동물의 아이디와 이름을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 시작일이 빠른 순으로 조회해야합니다.
풀이 과정
- 조건 확인
- 보호 시작일(ANIMAL_INS.
DATETIME
)보다 입양일(ANIMAL_OUTS.DATETIME
)이 더 빠른 동물만 찾아야 함
- 보호 시작일(ANIMAL_INS.
- 테이블 결합 (JOIN)
- 두 테이블을
ANIMAL_ID
를 기준으로 조인 - INNER JOIN 선택 이유 : 보호소에 들어온 동물 중 입양된 기록이 있는 동물만 필요하기 때문
- 두 테이블을
- 조건 필터링
- 보호 시작일이 입양일보다 더 늦은 경우만 선택하기 위해 WHERE AO.
DATETIME
< AI.DATETIME
조건 사용 - 입양일이 보호 시작일보다 더 빠른 동물을 선택해야 함
- 보호 시작일이 입양일보다 더 늦은 경우만 선택하기 위해 WHERE AO.
- 결과 정렬
- 정렬 기준에 따라 ORDER BY로 결과 정렬
- 보호 시작일(ANIMAL_INS.
DATETIME
)을 기준으로 오름차순 정렬
- 보호 시작일(ANIMAL_INS.
- 정렬 기준에 따라 ORDER BY로 결과 정렬
- 최종 결과 출력
- SELECT 절에서 동물의 아이디(
ANIMAL_ID
)와 이름(NAME
) 출력
- SELECT 절에서 동물의 아이디(
- 교훈
- 날짜 데이터 비교는 간단한 연산자로 가능하지만, Data Type을 항상 확인하여 일관성 있는 비교가 이루어지도록 할 것을 항시 염두하자..
- 오라클에서는 TO_DATE 쓰는게 익숙했는데 MySQL에서는 STR_TO_DATE 이렇게 다른 형태로 사용되는 군… DATE 타입 다루는 방법을 숙지해두도록 하자..
정답
1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT
AI.ANIMAL_ID,
AI.NAME
FROM
ANIMAL_INS AI
JOIN
ANIMAL_OUTS AO
ON
AI.ANIMAL_ID = AO.ANIMAL_ID
WHERE
AO.DATETIME < AI.DATETIME
ORDER BY
AI.DATETIME ASC;
Tip
- 날짜 비교
- Data Type이 DATE인 경우 일반적인 숫자 비교처럼 간단히
>
또는<
연산자로 비교 가능- 만약 Data Type이 문자열인 경우 TO_DATE(‘2023-01-01’, ‘YYYY-MM-DD’) 함수 사용하여 DATE 형식으로 변환하여 비교하기. (MYSQL에서는 STR_TO_DATE(‘2025-01-31’, ‘%Y-%m-%d’))
- + 안전하게 문자열 비교하기
- 날짜가 문자열로 저장된 경우, 데이터가 예상치 못한 형식으로 저장되거나 정렬 순서가 깨질 수 있음
- 따라서 항상 변환 후 비교하면 데이터 정합성을 보장하는 것을 추천
SQL Dialect Used: Oracle
개념 확인
- INNER JOIN
- 두 테이블의 공통된 컬럼을 기준으로 데이터를 연결
- 양쪽 테이블 모두에 일치하는 행만 결과에 포함됨
- *DATE 형식 비교 vs 문자열 비교
- 날짜 데이터: 오라클과 MySQL에서 DATE 또는 DATETIME 형식이면 바로 비교 가능
- 문자열 데이터: 문자열로 저장된 경우 변환 후 비교하는 것을 추천
- 오라클:
TO_DATE()
- MySQL:
STR_TO_DATE()
Useful link
This post is licensed under Park Juyoung by the author.