[데이터베이스 SQL 완전정복 목차]
안녕하세요~ 양햄찌 블로그 주인장입니다.
운영체제, 리눅스유닉스 카테고리에 이어 데이터베이스 파트도 차근차근 이어가보려고 하는데
갈길이 머네요 ㅎㅎ
오늘은 무슨 포스팅을 쓸까하다가 쉬운거부터 쓰는게 나을거같아서 골라온 ROWNUM입니다!
[목차]
ROWNUM 역할?!
만약 직원들의 정보가 담겨있는 EMPLOYEES 테이블이 있는데 여기서 연봉이 가장 큰 10사람만 뽑고싶어!
이럴 수 있죠~~~ 굳이 모든 데이터를 검색하지 않고, 특정 개수만큼 원하는 데이터를 추출하고 싶을 때 ROWNUM을 사용할 수 있습니다.
또 그냥 데이터만 추출하는게 아니라 1,2,3,4,5,,, 이렇게 순번을 매기고 싶을 수 있겠죠? 그럴 때에도 ROWNUM이 쓰입니당
사용법은 이렇게 간단합니다! 샘플 무료 스키마인 EMPLOYEES 테이블에서 결과를 각각 확인해볼게요
첫 번째 결과로 데이터 맨 앞에 순번이 추가된 것을 확인할 수 있고, (물론 그 뒤에 데이터가 쭈르륵 있는데 사진은 자른거예요 ㅎㅎ)
두 번째 쿼리 명령어로 10개의 데이터만 뽑힌 것을 알 수 있어요. 딱 10개만 뽑힌거!
ROWNUM = 1 등호 연산자 사용불가?!
그럼 ROWNUM은 등호 사용이 가능한가? 궁금하신 분이 있을거예요
예를 들어 ROWNUM = 1 하면 하나의 행만 추출되고 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을 중점으로 알아봤어요. 도움이 되었다면 공감 감사합니다.
'별걸다하는 IT > 데이터베이스 Database' 카테고리의 다른 글
[SQL] 현재 날짜 시간 정보 알려주는 sysdate 함수, 포맷 자유자재 변경하기 (0) | 2021.09.29 |
---|---|
[SQL] 정렬하기 order by 쿼리 사용법 1, 2 desc 의미 (0) | 2021.08.24 |
[SQL] 순위 매기는 함수 - ROW_NUMBER(), RANK(), DENSE_RANK() (1) | 2021.05.20 |
[데이터베이스 SQL 기초] 오라클, MySQL 결과 중복 제거 DISTINCT에 사용법 (0) | 2021.04.01 |
[오라클 MySQL 기초] BETWEEN, NOT BETWEEN 쿼리 결과 범위 조회하는 법, 비트윈사용법 (0) | 2021.03.30 |
최신 댓글