빡코

[SQL] 오랜 기간 보호한 동물(1) 본문

카테고리 없음

[SQL] 오랜 기간 보호한 동물(1)

chris.djang 2020. 1. 30. 16:02

https://programmers.co.kr/learn/courses/30/lessons/59044

 

 

코딩테스트 연습 - 오랜 기간 보호한 동물(1) | 프로그래머스

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다. NAME TYPE NULLABLE ANIMAL_ID VARCHAR(N) FALS

programmers.co.kr

 

출력

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

 

시도방법

1.LEFT OUTER JOIN를 이용해서 값을 뽑아내는데까지는 성공하였다. 하지만, 조건인 ' 동물 3마리의 이름과 보호 시작일을 조회'을 만족시켜야 했다. 여기까지의 쿼리문과 결과값. 

SELECT ANIMAL_INS.NAME, ANIMAL_INS.DATETIME 
FROM ANIMAL_INS 
LEFT OUTER JOIN ANIMAL_OUTS
ON ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID
WHERE ANIMAL_OUTS.ANIMAL_ID IS NULL
ORDER BY ANIMAL_INS.DATETIME;

 

조건을 만족시키위해서는 nameBenji 출력이 되어야하지만, 총 4개의 값이 출력이 되었다. 

이부분에서 'ROWNUM <= 3' 이는 조건을 주면 원하는 결과값을 얻을 수 있다.  

 

수정된 쿼리문은 아래와 같다 

SELECT * FROM (
SELECT ANIMAL_INS.NAME, ANIMAL_INS.DATETIME 
FROM ANIMAL_INS 
LEFT OUTER JOIN ANIMAL_OUTS
ON ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID
WHERE ANIMAL_OUTS.ANIMAL_ID IS NULL
ORDER BY ANIMAL_INS.DATETIME
)
WHERE ROWNUM <= 3;

 

최종 출력값. 성공이다.

 

참조 풀이법

 

풀이1. 

SELECT result.name,result.datetime
from(
    select rownum rnum, re.name name, re.datetime datetime
    from (select * from animal_ins ins
          where ins.animal_id not in(select animal_id from animal_outs)
         order by ins.datetime) re
)result
where result.rnum<=3;

 

풀이2

SELECT * FROM
(SELECT A.NAME, A.DATETIME
FROM ANIMAL_INS A LEFT JOIN ANIMAL_OUTS B
ON A.ANIMAL_ID = B.ANIMAL_ID
WHERE B.ANIMAL_ID IS NULL
ORDER BY A.DATETIME)
WHERE ROWNUM<=3

 

 

관련 개념

1.LEFT OUTER JOIN

조인 수행시 먼저 표기된 좌측 테이블에 해당하는 테이터를 먼저 읽은 후, 나중 표기된 우측 테이블에서 JOIN 대상 테이터를 읽어옵니다. 즉 Table A와 B가 있을 때 (Table A 가 기준이 됨) A와 B를 비교해서 B의 JOIN 컬럼에서 같은 값이 있을 때 해당 데이터를 가져오고, B의 JOIN 컬럼에서 같은 값이 없는 경우에는 B테이블에서 가져오는 컬럼들은 NULL 값으로 채웁니다. OUTER 키워드는 생략할 수 있습니다.

 

SELECT  
FROM Table A  
LEFT JOIN Table B 
ON A.Key = B.Key 
WHERE B.Key is NULL;

2. ROWNUM 

ROWNUM을 사용하는 방법 

1. ROWNUM 키워드 이용하는 방법

SELECT ROWNUM
     , A.*
  FROM SCOTT.EMP A
 ORDER BY A.ENAME

 

SELECT ROWNUM
     , X.*
  FROM ( SELECT A.*
           FROM SCOTT.EMP A
          ORDER BY A.ENAME
       ) X

2. ROW_NUMBER() 함수를 사용하는 방법

SELECT ROW_NUMBER() OVER(ORDER BY A.JOB, A.ENAME) NUM
     , A.*
  FROM SCOTT.EMP A
 ORDER BY A.JOB, A.ENAME

 

그룹별(PARTITION)로 순번을 따로 부여할 수 있다.

SELECT ROW_NUMBER() OVER(PARTITION BY A.JOB ORDER BY A.JOB, A.ENAME) NUM
     , A.*
  FROM SCOTT.EMP A
 ORDER BY A.JOB, A.ENAME

 

 

참조

https://gent.tistory.com/170