ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다.
| NAME | TYPE | NULLABLE |
|---|---|---|
| ANIMAL_ID | VARCHAR(N) | FALSE |
| 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 테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME는 각각 동물의 아이디, 생물 종, 입양일, 이름, 성별 및 중성화 여부를 나타냅니다. ANIMAL_OUTS 테이블의 ANIMAL_ID는 ANIMAL_INS의 ANIMAL_ID의 외래 키입니다.
| NAME | TYPE | NULLABLE |
|---|---|---|
| ANIMAL_ID | VARCHAR(N) | FALSE |
| ANIMAL_TYPE | VARCHAR(N) | FALSE |
| DATETIME | DATETIME | FALSE |
| NAME | VARCHAR(N) | TRUE |
| SEX_UPON_OUTCOME | VARCHAR(N) | FALSE |
천재지변으로 인해 일부 데이터가 유실되었습니다. 입양을 간 기록은 있는데, 보호소에 들어온 기록이 없는 동물의 ID와 이름을 ID 순으로 조회하는 SQL문을 작성해주세요.
예를 들어, ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블이 다음과 같다면
ANIMAL_INS
| ANIMAL_ID | ANIMAL_TYPE | DATETIME | INTAKE_CONDITION | NAME | SEX_UPON_INTAKE |
|---|---|---|---|---|---|
| A352713 | Cat | 2017-04-13 16:29:00 | Normal | Gia | Spayed Female |
| A350375 | Cat | 2017-03-06 15:01:00 | Normal | Meo | Neutered Male |
ANIMAL_OUTS
| ANIMAL_ID | ANIMAL_TYPE | DATETIME | NAME | SEX_UPON_OUTCOME |
|---|---|---|---|---|
| A349733 | Dog | 2017-09-27 19:09:00 | Allie | Spayed Female |
| A352713 | Cat | 2017-04-25 12:25:00 | Gia | Spayed Female |
| A349990 | Cat | 2018-02-02 14:18:00 | Spice | Spayed Female |
ANIMAL_OUTS 테이블에서
ANIMAL_INS에 없으므로, Allie의 데이터는 유실되었습니다.ANIMAL_INS에 있으므로, Gia의 데이터는 유실되지 않았습니다.ANIMAL_INS에 없으므로, Spice의 데이터는 유실되었습니다.따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.
| ANIMAL_ID | NAME |
|---|---|
| A349733 | Allie |
| A349990 | Spice |
본 문제는 Kaggle의 "Austin Animal Center Shelter Intakes and Outcomes"에서 제공하는 데이터를 사용하였으며 ODbL의 적용을 받습니다.
LEFT OUTER JOIN 활용
LEFT OUTER JOIN을 통해JOIN연산 진행 후,ANIMAL_INS테이블의 특정 컬럼인ANIMAL_TYPE이 NULL인 조건을 걸어준다.NOT EXISTS 활용
NOT EXISTS (서브쿼리)형식으로 존재 유무룰 판단한다.
SELECT AO.ANIMAL_ID,AO.NAME
FROM ANIMAL_OUTS AS AO
LEFT OUTER JOIN ANIMAL_INS AS AI
USING (ANIMAL_ID)
WHERE AI.ANIMAL_TYPE IS NULL;
SELECT ANIMAL_ID, name
FROM ANIMAL_OUTS AO
WHERE NOT EXISTS (
SELECT 1 FROM ANIMAL_INS WHERE animal_id = AO.animal_id);
SQL에서 SELECT 1을 사용하는 것은 서브쿼리나 특정 조건을 만족하는지를 확인하는 용도로 자주 사용됩니다. 주로 EXISTS 절과 함께 사용되며, 쿼리의 존재 여부를 확인하는데 집중합니다.
SELECT 1의 의미SELECT 1은 숫자 1을 선택합니다.EXISTS 절과 함께 사용EXISTS는 서브쿼리가 하나 이상의 행을 반환하는지 확인하는 조건문입니다.EXISTS 절 내부에서 SELECT 1을 사용하면, 조건에 맞는 행이 존재하는지만 확인할 수 있습니다.SELECT *
FROM ANIMAL_INS o
WHERE EXISTS (SELECT 1 FROM ANIMAL_INS WHERE animal_id = o.animal_id);
ANIMAL_INS 테이블의 각 행에 대해 동일한 animal_id를 가진 행이 존재하는지 확인합니다. 존재하면 해당 행을 결과로 반환합니다.SELECT 1은 특정 행이 존재하는지만 확인하기 때문에, 실제로 반환되는 데이터는 중요하지 않습니다.SELECT * 대신 SELECT 1을 사용하면 쿼리가 약간 더 효율적으로 실행될 수 있습니다. 이는 데이터베이스가 실제로 모든 컬럼을 가져올 필요가 없기 때문입니다.SELECT 1의 실제 사용 예시SELECT CASE
WHEN EXISTS (SELECT 1 FROM ANIMAL_INS WHERE animal_id = 'A123')
THEN 'Exists'
ELSE 'Does not exist'
END;
ANIMAL_INS 테이블에서 animal_id가 'A123'인 행이 존재하는지 확인하고, 존재하면 'Exists', 존재하지 않으면 'Does not exist'를 반환합니다.SELECT animal_id
FROM ANIMAL_INS o
WHERE EXISTS (SELECT 1 FROM ANIMAL_INS WHERE animal_id = o.animal_id AND condition);
ANIMAL_INS 테이블에서 특정 조건을 만족하는 animal_id가 존재하는지 확인하여, 해당 animal_id를 반환합니다.SELECT 1은 서브쿼리에서 행의 존재 여부만을 확인하기 위해 사용됩니다.EXISTS 절과 함께 사용되며, 불필요한 데이터 조회를 방지하여 쿼리의 효율성을 높입니다.