-
[SQL/프로그래머스] 오랜 기간 보호한 동물(1) rownum, rank()코딩테스트/프로그래머스 2023. 3. 15. 11:03
https://school.programmers.co.kr/learn/courses/30/lessons/59044
아직 입양을 못 간 동물 중, 가장 오래 보호소에 있었던 동물 3마리의 이름과 보호 시작일을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 시작일 순으로 조회해야 합니다.
📑 rownum 사용해보기
mysql에는 top이라는 함수가 있지만 oracle에는 존재하지 않는다. 따라서 순위를 매기려면 rownum 함수를 이용해야 한다.
rownum은 테이블에는 존재하지 않지만 열의 데이터가 숫자로 출력된다. 의사열이라는 특수열로, 의사 열은 데이터가 저장되는 실제 테이블에 존재하지 않지만 특정 목적을 위해 테이블에 저장되어 있는 열처럼 사용 가능한 열을 뜻한다.
scott 계정에 있는 emp 테이블을 이용해 rownum을 사용해보자.
위의 처럼 입력하면 rownum이 뒤죽박죽 나온 것을 확인할 수 있다. rownum은 데이터를 하나씩 추가할 때 매겨지는 번호이므로 order by 절을 통해 정렬해도 이미 정해진 순번이 유지되는 특성이 있다. 이 특성을 인라인 뷰에 적용하면 select문의 결과 순번을 매겨서 출력할 수 있다.
--인라인뷰 (서브쿼리 사용) select rownum , x.* from ( select rownum , e.* from emp e order by sal desc ) x; -- 인라인뷰(with절 사용) with 인라인뷰 as (select * from emp order by sal desc) select rownum, 인라인뷰.* from 인라인뷰 ;
📑 rownum으로 문제 풀어보기
입양을 가지 못한 데이터를 출력하기 위해 서브쿼리에서 not in을 사용하였다. rownum을 사용하기 위해 from 절에 인라인 뷰를 사용한 걸 확인할 수 있다.
SELECT NAME, DATETIME FROM ( SELECT NAME, DATETIME , ROWNUM FROM ANIMAL_INS WHERE ANIMAL_ID NOT IN ( SELECT ANIMAL_ID FROM ANIMAL_OUTS ) ORDER BY DATETIME ) WHERE ROWNUM <4 ;
** 인라인뷰를 사용하지 않고 order by를 통해 rownum을 조건으로 줬을 경우 (잘못된 조회)
SELECT NAME, DATETIME , ROWNUM FROM ANIMAL_INS WHERE ANIMAL_ID NOT IN ( SELECT ANIMAL_ID FROM ANIMAL_OUTS ) ORDER BY DATETIME;
📑 rank 사용하기
rownum이 아닌 rank를 사용해서도 구할 수 있다.
select name, datetime from ( select name, datetime, rank() over ( order by datetime ) as rnk FROM ANIMAL_INS AI WHERE NOT EXISTS ( SELECT ANIMAL_ID FROM ANIMAL_OUTS AO WHERE AI.ANIMAL_ID = AO.ANIMAL_ID ) ) where rnk <4 ;
📑 where 절에서 alias
alias를 where 절에서 사용하면 에러가 발생한다. 따라서 alias로 줄여서 사용하고 싶을때는 서브쿼리를 이용해서 사용해야 한다. 이부분 참고 !
반응형'코딩테스트 > 프로그래머스' 카테고리의 다른 글
[SQL/프로그래머스] 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기 (0) 2023.03.17 [SQL/프로그래머스] 헤비 유저가 소유한 장소 , 다중행 서브쿼리, 인라인뷰, 분석함수 (0) 2023.03.16 [SQL/프로그래머스] 없어진 기록 찾기 (NOT IN, NOT EXISTS) (0) 2023.03.15 [SQL/프로그래머스] 조건에 맞는 회원수 구하기, 특정 날짜 조건 주기 (0) 2023.01.20 [SQL/프로그래머스] 경기도에 위치한 식품창고 목록 출력하기, CASE (0) 2023.01.17