본문 바로가기

database

oracle - 연산자 우선순위, ORDER BY, ROWNUM

19.11.22. 연산자 우선순위, ORDER BY, ROWNUM

데이터베이스 구현

2019-12-01 21:39:14


객체의 이름은 30자 이내, 무조건 알파벳으로 시작.

숫자, 특수문자 중에는 _, $ 사용 가능.

객체의 이름은 무조건 대문자로 저장된다.

 

-- != 사용

SELECT *

FROM emp

WHERE deptno !=10

AND hiredate > TO_DATE('19810601','yyyymmdd');

=> emp 테이블에서 부서 번호가 10이 아니고, 입사날짜가 1981.06.01 이후인 직원 조회.

 

--위에 것 NOT IN 사용

SELECT *

FROM emp

WHERE deptno NOT IN (10)

AND hiredate > TO_DATE('19810601','yyyymmdd');

 

dbms 가 오라클을 받으면 읽기 편하게 바꾸는데, 이 과정에서 LIKE연산자 사용 후 % 나 _가 안 쓰여있으면
범위로 분석할 필요가 없어서 ' = ' 으로 생각한대. 신기한 게 많다.

=> 뭔 소리지

 

▶연산자 우선순위

1. 산술 연산자 (*, /, +, -)

2. 문자열 결합( || )

3. 비교 연산(=, <=, <, >=, >)

4. IS, [NOT] NULL, LIKE, [NOT] IN

5. [NOT] BETWEEN

6. NOT

7. AND

8. OR

일반 수학과 마찬가지로 괄호를 통해 우선순위를 변경할 수 있다.

 

1. 직원 이름이 SMITH이거나, ALLEN 이면서 역할이 SALESMAN 인 직원 조회

SELECT *

FROM emp

WHERE ename = 'SMITH'

OR ename = 'ALLEN'

AND job = 'SALESMAN';

 

2. 위의 것은 연산자 우선순위로 AND 부분이 먼저 실행된다. 헷갈리지 않게 바꿔보자.

SELECT *

FROM emp

WHERE ename = 'SMITH'

OR (ename = 'ALLEN' AND job = 'SALESMAN');

 

3. job 이 SALESMAN 이거나 사원번호가 78로 시작하며, 입사날짜가 1981.06.01 이후인 사원 조회.

SELECT *

FROM emp

WHERE job = 'SALESMAN'

OR empno LIKE '78%'

AND hiredate > TO_DATE('19810601','yyyy.mm.dd');

 

▶데이터 정렬

- TABLE 객체에는 데이터를 저장/조회 시 순서를 보장하지 않는다.

- 보편적으로 데이터가 입력된 순서대로 조회됨.

-데이터가 항상 동일한 순서로 조회되는 것을 보장하지 않음.

- ORDER BY

ASC : 오름차순(기본) : 작은 값부터 점점 올라가는 형태.

DESC : 내림차순 : 큰 값부터 점점 내려가는 형태.

 

ORDER BY ename;  =  ORDER BY ename ASC;

=> 둘 다 ename 을 오름차순으로 정렬함.

ORDER BY ename DESC;

=>내림차순으로 정렬함.

ORDER BY ename DESC, mgr;

=> ename 은 내림차순, mgr은 오름차순으로 정렬함.

 

1. emp테이블에서 모든 직원의 정보를 직원 이름으로 오름차순 정렬함.

SELECT *

FROM emp

ORDER BY ename ASC; 

 

2. emp테이블에서 부서 번호로 오름차순 정렬하고, 부서 번호가 같을 때에는 sal을 내림차순으로,

   sal 이 같을때에는 이름으로 오름차순 정렬함.

SELECT *

FROM emp

ORDER BY deptno, sal DESC, ename;

 

3. 조회하는 칼럼의 위치를 인덱스로 표현 가능.

SELECT empno, deptno, sal, ename nm

FROM emp

ORDER BY 3;

 =>SELECT 절의 세 번째 컬럼(sal) 을 오름차순 정렬함.

    해당 쿼리가 수정되지 않는다는 전제조건하에는 사용해도 괜찮지만

    컬럼이 수정될 시에는 의도하지 않은 결과를 출력할 수도 있다.

ROWNUM

1. tool 이 제공해주는 '행의 번호'를 컬럼으로 가질 수 있다.

SELECT ROWNUM, deptno, ename

FROM emp

ORDER BY deptno;

 => emp 테이블에서 ROWNUM 가상 컬럼과 deptno, ename 컬럼을 조회 후 deptno 오름차순 정렬.

  위는 ROWNUM을 매긴 후에 ORDER BY정렬이 되었다.

 

2. 위를 정렬 후 로우 넘을 달아보자.

SELECT ROWNUM, a*

FROM

(SELECT deptno, ename

FROM emp

ORDER BY deptno) a;

  => 괄호 안쪽 from절에서 order by 정렬 후에 괄호에 알리아스를 주었다. (a)

  괄호로 묶어 전체를 하나의 테이블로 치부하고, 이 속에서 ROWNUM 을 달았음.

  "inline view" 라고 부름. (괄호를 사용하는 것.)

  괄호 밖 SLECT 절의 a.* 은 a의 모든 컬럼을 조회한다는 뜻이다. ROWNUM 이 있을 때에는

  " * "을 " , " 바로 뒤에 사용할 수 없어서 알리아스를 주고 " * " 를 주었다.

 

 

-ROWNUM 은 이미 읽은 데이터에 순서를 부여하는 것.

아직 읽지 않은 데이터가 존재하는 조건에서는 사용할 수 없다.

 

SELECT ROWNUM, empno, ename

FROM emp

WHERE FOWNUM =1;

=> ROWNUM 은 equal ( = ) 비교가 1만 가능하다. equal 뒤에 2는 올 수 없다.

 

3. 다음과 같은 형태 가능

1. WHERE ROWNUM = 1;

2. WHERE ROWNUM <=2;

3. WHERE ROWNUM < 4

4. BETWEEN 1 AND 10;

  => ROWNUM이 1인 것만 조회, 1부터 시작하는 것 조회는 가능. 중간부터 조회는 불가능.

   BETWEEN .... AND 절에서도 1부터만 조회 가능.

 

-SELECT 절과 ORDER BY 구문의 실행 순서

SELECT -> ROWNUM -> ORDER BY

 

*테이블 속에 컬럼이 존재.

* ROWNUM 언제 사용하나? : 게시판 등에서 페이징처리 라는 기술이 있음. 이때 사용된다.

 

4. ROWNUM의 중간 부분부터 조회하려면 어떻게 할까?

SLECT a.*

FROM

(SELECT ROWNUM A, empno, ename

FROM emp) a

WHERE A BETWEEN 11 AND 20;

=> 먼저 rownum과 조회할 컬럼을 select 하고, rownume 은 between ...and ... 절에 올 수 없으니,

 rownum에 알리아스를 준다.

   이후 이것을 괄호에 묶어 from 절에 넣고 다시 select와 where 절을 넣었다.

  로우넘을 먼저 매기고, 로우넘과 괄호에 별칭을 주고, 괄호 밖에 where 절을 사용하면 됨.

 

 

5. emp 테이블에서 ename으로 정렬한 이후에, 그 결과의 11~14번째 행만 조회하는 쿼리를 작성해라.

SELECT *

FROM 

(SELECT ROWNUM rn , a.*

FROM

(SELECT *

FROM emp

ORDER BY ename) a  ) b

WHERE rn BETWEEN 11 AND 14;

  => 가장 먼저 emp 테이블 전체를 ename 으로 정렬했다. (a)

       두 번째로 정렬된 a 를 from 절에 두고, ROWNUM과 a 전체 컬럼을 select 절에 두었다. (b)

       세 번째로 ROWNUM을 매긴 b 를 from 절에 두고, b속의 ROWNUM(알리아스 : rn) 을

       where 절에 넣어 범위를 설정 후 전체를 조회했다.