본문 바로가기

별걸다하는 IT/데이터베이스 Database

[오라클 SQL] ROWNUM - 특정 개수의 행만 조회하기, 행 번호 매기기 rownum = 2, order by rownum

반응형

[데이터베이스 SQL 완전정복 목차]

안녕하세요~ 양햄찌 블로그 주인장입니다.

운영체제, 리눅스유닉스 카테고리에 이어 데이터베이스 파트도 차근차근 이어가보려고 하는데 

갈길이 머네요 ㅎㅎ

 

오늘은 무슨 포스팅을 쓸까하다가 쉬운거부터 쓰는게 나을거같아서 골라온 ROWNUM입니다!

[목차]

1. ROWNUM 역할

2. ROWNUM=1 과 ROWNUM=2

3. WHERE절에서 ROWNUM과 ORDER BY

4. SELECT절에서 ROWNUM과 ORDER BY

5. MySQL, MariaDB에서는 LIMIT

 

ROWNUM 역할?!

만약 직원들의 정보가 담겨있는 EMPLOYEES 테이블이 있는데 여기서 연봉이 가장 큰 10사람만 뽑고싶어!

이럴 수 있죠~~~ 굳이 모든 데이터를 검색하지 않고, 특정 개수만큼 원하는 데이터를 추출하고 싶을 때 ROWNUM을 사용할 수 있습니다.

 

또 그냥 데이터만 추출하는게 아니라 1,2,3,4,5,,, 이렇게 순번을 매기고 싶을 수 있겠죠? 그럴 때에도 ROWNUM이 쓰입니당

사용법은 이렇게 간단합니다! 샘플 무료 스키마인 EMPLOYEES 테이블에서 결과를 각각 확인해볼게요 

1,2,3,4,,,순서를 보여주는 rownum이 추가됨

첫 번째 결과로 데이터 맨 앞에 순번이 추가된 것을 확인할 수 있고, (물론 그 뒤에 데이터가 쭈르륵 있는데 사진은 자른거예요 ㅎㅎ)

두 번째 쿼리 명령어로 10개의 데이터만 뽑힌 것을 알 수 있어요. 딱 10개만 뽑힌거!

 

ROWNUM = 1 등호 연산자 사용불가?!

그럼 ROWNUM은 등호 사용이 가능한가? 궁금하신 분이 있을거예요

예를 들어 ROWNUM = 1 하면 하나의 행만 추출되고 ROWNUM = 2 하면 두개의 행만 추출되는거죠!

 rownum = 2의 경우 데이터가 안뽑힘!

실제 실행해보면 rownum =1 은 하나의 행만 뽑히는데 rownum =2 는 아무것도 안뽑혀요! rownum =3, rownum = 4,, rownum=10 모두 조회결과가 0인것을 알 수 있습니다.

 

이유는 rownum 작동방식에 있는데요,

rownum은 테이블 where절이 실행될 때 조건에 맞으면 1을 부여하고 맞지 않으면 번호를 부여하지 않고 버리는 방식으로 진행됩니다.

만약 조건이 rownum = 1일 경우 WHERE 조건 후 첫 번째 행에서 rownum =1 을 만족하니까 하나의 데이터를 가져옵니다. 하지만 rownum = 2 일 경우 WHERE 조건 결과의 첫 번째 행의 순번이 2가 아닌 1이니까 이 결과를 버리게 되고, 2가 버려졌으니 그 다음에 만족하는 행 또한 1이 될텐데 조건 2에 부합되지 않으니까 또 버려집니다. 결국 이런 작동방식으로 인해 rownum=1이 아니면 어떤 결과도 추출될 수 없는거예요!

이해가 되시나요~?!?

반응형

정렬 ORDER BY 와 ROWNUM 사용시 주의할 점 (WHERE)

직원 테이블에서 가장 큰 연봉을 가진 10사람 정보를 뽑고 싶어요

그래서.. 이렇게 쿼리를 짰는데...!

[잘못된쿼리]

SELECT e.SALARY, e.*
FROM EMPLOYEES e 
WHERE ROWNUM <= 3
ORDER BY e.SALARY DESC

제대로 추출됐는지 확인해볼까요? 미리 말하자면 이는 잘못된 쿼리입니다.

나와야 하는 결과

여기서 10개까지 데이터인 저 빨간색 박스 부분만 추출되어야 하는데.. 즉 최고 금액이 24,000 그리고 최저가 11,500이 되어야하는데

실제 결과

실제 실행해보면 최저가 4,200으로 내가 원하는 결과가 아닌 것을 확인할 수 있어요.

[order by rownum 같이 썼을때 결과 이유]

이 원인 또한 rownum 작동 원리에 있는데요,

WHERE절이 실행되었을 때 줄세우기를 하기 때문에 그냥 테이블 조회시 처음부터 10개 데이터에 순번을 매기고 그 결과값을 정렬한 것에 지나지 않는답니다.

정렬을 먼저 하고 10개를 추출하는게 아니라, 10개를 추출하고 거기서 정렬한 것이기 때문에 이렇다는거!

 

[올바른쿼리]

그래서 정렬을 먼저 해주고 그 결과를 rownum 매길 수 있도록 inner 쿼리를 써야해요

SELECT SALARY,	a.*
FROM (
	SELECT 		*
	FROM 		EMPLOYEES
	ORDER BY	SALARY DESC 
) a
WHERE rownum <= 10;

요렇게 정렬을 먼저 한 이후에 그 결과로 rownum 절을 사용해주면 

이 처럼 SALARY가 높은 10개의 직원정보만 딱 보여줍니다.

 

select 에서의 rownum과 order by

위처럼 WHERE절의 rownum 말고 순번매길 때 select에서 사용하는 ROWNUM도 마찬가지입니다.

위처럼 쿼리를 짜면 정렬 후에 번호를 매기는게 아니라, 이렇게 번호 매겨진게 정렬되게 됩니다.

이유는 위에서 설명했던 작동 방식과 동일!

SELECT rownum,salary,a.*
FROM (
	SELECT 		*
	FROM 		EMPLOYEES
	ORDER BY	SALARY DESC 
) a

요렇게 정렬을 먼저 진행해준 다음에 그 쿼리를 감싸서 rownum을 사용해줘야해요. 

 

오라클이 아닌 다른 DBMS의 특정 갯수만큼 추출하기

ROWNUM은 오라클에서 사용되는 절인데요.

간단히 언급만 하고 넘어가자면 MySQL에서는 LIMIT를 사용하면 동일하게 원하는 개수만큼 데이터를 조회할 수 있습니다. (오라클에서는 LIMIT 사용 안됨!)

SELECT *
FROM EMPLOYEES
LIMIT 5;

결과테이블에서 5개 행을 가져오는 쿼리입니다.

LIMIT는 특이하게 WHERE절이 없어도 정상적으로 수행되죠? LIMIT는 RONWUM과 다르게 ORDER BY랑 같이 썼을 때 ORDER BY까지 모두 실행된 결과에서 원하는 행의 데이터를 가져옵니다. 따라서 ROWNUM처럼 서브쿼리(=이너쿼리)를 사용할 필요가 없는 것이죠~! 자세한 사항은 나중에 LIMIT 포스팅에서 따로 알아봅시다.

 

오늘은 여기까지~

행 개수를 내가 원하는 만큼 뽑고 순번을 매길 수 있는 rownum을 중점으로 알아봤어요. 도움이 되었다면 공감 감사합니다.

반응형