2020년 7월 19일 일요일

오라클, SQL 조건연산자를 이용한 조건검색, LIKE, IS NULL

오라클, SQL 조건연산자를 이용한 조건검색, LIKE, IS NULL

http://ojc.asia/bbs/board.php?bo_table=LecSQLnPlSql&wr_id=604

3.2.6 SQL 조건연산자를 이용한 조건검색

BETWEEN A AND B

A와 B의 사이의 값, 경계 A,B 도 포함

A보다 크거나 같고 B보다 적거나 같다.

(AND로 해석)

IN(A, B, …, N)

A, B, … N 중의 하나와 일치하면 참

(OR로 해석)

-- MYEMP1 테이블에서 입사일자가 2013년 10월25일~2014년12월31일 사이의 입사자 수 출력, 먼저 두가지 쿼리를 보자.

SQL> SELECT COUNT(*) FROM MYEMP1

WHERE TO_CHAR(HIREDATE,'RR/MM/DD') >= '13/10/26'

AND TO_CHAR(HIREDATE,'RR/MM/DD') <= '14/12/31';

COUNT(*)

----------

1440288

경 과: 00:00:16.60

SQL> SELECT COUNT(*) FROM MYEMP1

WHERE HIREDATE >= '13/10/26'

AND HIREDATE < '15/01/01';

COUNT(*)

----------

1440288

경 과: 00:00:17.20

-- 위 두 쿼리의 차이는 WHERE절 HIREDATE칼럼에 SQL함수 TO_CHAR가 적용되었느냐의 여부다. 현재 MYEMP1의 HIREDATE 칼럼에는 검색을 빠르게 해주는 인덱스가 생성되어 있지 않다. 인덱스라는 것을 만든 후 두 쿼리를 다시 실행하여 실행시간의 차이에 대해 확인하자.

SQL> CREATE INDEX IDX_MYEMP1_HIREDATE ON MYEMP1(HIREDATE);

-- 아래 쿼리는 HIREDATE 칼럼에 SQL함수 TO_CHAR가 적용되어 칼럼값에 변형이 생겨 만들어 놓은 인덱스를 이용하지 못한다.

SQL> SELECT COUNT(*) FROM MYEMP1

WHERE TO_CHAR(HIREDATE,'RR/MM/DD') >= '13/10/26'

AND TO_CHAR(HIREDATE,'RR/MM/DD') <= '14/12/31';

COUNT(*)

----------

1440288

경 과: 00:00:16.53

Execution Plan

--------------------------------------------------------------------------------------------

Id Operation Name Rows Bytes Cost (%CPU) Time

---------------------------------------------------------------------------------------------

0 SELECT STATEMENT 1 9 25678 00:05:09

1 SORT AGGREGATE 1 9 |

* 2 | TABLE ACCESS FULL MYEMP1 25000 219K 25678 00:05:09

---------------------------------------------------------------------------------------------

-- 아래 쿼리의 실행계획을 보면 인덱스를 경유하여 데이터를 추출한 것을 알 수있다. 두 쿼리중 어떤 쿼리를 사용해야 할지 고민해 보자.

SQL> SELECT COUNT(*) FROM MYEMP1

WHERE HIREDATE >= '13/10/26'

AND HIREDATE < '15/01/01';

COUNT(*)

----------

1440288

경 과: 00:00:00.71 -- 1초도 걸리지 않는다.

Execution Plan

------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 9 | 123 (1)| 00:00:02 |

| 1 | SORT AGGREGATE | | 1 | 9 | | |

|* 2 | FILTER | | | | | |

|* 3 | INDEX RANGE SCAN| IDX_MYEMP1_HIREDATE | 25000 | 219K| 123 (1)| 00:00:02 |

------------------------------------------------------------------------------------------

-- BETWEEN ~ AND ~는 AND연산으로 변형할 수 있다.

SQL> select empno, ename, sal

from emp

where sal between 1000 and 5000;

EMPNO ENAME SAL

---------- -------------------- --------

7499 ALLEN 1,600

7521 WARD 1,250

7566 JONES 2,975

7654 MARTIN 1,250

SQL> select empno, ename, sal

from emp

where sal >= 1000

and sal <= 5000;

-- EMP 테이블에서 부서코드가 10 or 20 or 30인 사원의 사번, 이름, 급여를 출력하라. IN 연산자는 or로 풀어쓸 수 있다.

SQL> select empno, ename, sal

from emp

where deptno in (10, 20, 30);

EMPNO ENAME SAL

---------- -------------------- --------

7369 SMITH 800

7499 ALLEN 1,600

7521 WARD 1,250

……

SQL> select empno, ename, sal

from emp

where deptno = 10

or deptno = 20

or deptno = 30;

-- MYEMP1, MYSUGANG1 테이블에서 두과목 이상 수강한 사원의 사번, 이름을 출력하라.

SQL> SELECT EMPNO, ENAME FROM MYEMP1 E

WHERE EMPNO IN (

SELECT EMPNO FROM MYSUGANG1 S

GROUP BY EMPNO, LECTURE_ID

HAVING COUNT(*) > 1

)

LIKE

패턴 비교,부분적으로 일치(%, _ )하면 참

IS NULL

NULL 이면 참

IS NOT NULL

NULL이 아니면 참

LIKE : Query 조건으로 와일드카드를 사용 할 때 이용 한다. 와일드 카드인 ‘%’는 0개 이

상의 문자, ‘_’(Under bar)는 한 개의 문자를 의미 한다. 또한 비교하려는 문자에 ‘%’, ‘_’등

이 포함되어 있어 와일드 카드로서의 의미보다는 문자로서(리터럴값 자체)의 의미를 나타내기 위해서는 ESCAPE 옵션을 이용 한다.

--아래는 이름이 S로 시작하는 사원의 이름, 급여를 선택하는 질의임.

SQL> select ename, sal from emp

where ename like 'S%';

ENAME SAL

---------- ----------

SMITH 800

SCOTT 3000

SQL> select ename from emp;

ENAME

----------

SMITH

……

JONES

JAMES

ADAMS

SQL> select ename, sal from emp

where ename like 'J___S'; -- 언더바 3개(첫글자는 J, 이후 세 글자 오고 마지막은 S)

ENAME SAL

---------- ----------

JONES 2975

JAMES 950

SQL> insert into emp (empno, ename, sal) values (7777, 'J_SARA',700);

SQL> insert into emp (empno, ename, sal) values (7778, 'J_PAGE',800);

SQL> commit;

-- 이름이 J_로 시작하는 직원의 이름, 급여를 출력하세요

(잘못된 문장)

SQL> select ename, sal from emp

where ename like 'J_%';

ENAME SAL

---------- ----------

JONES 2975

JAMES 950

J_SARA 700

J_PAGE 800

-- 아래처럼 ESCAPE를 사용해야 한다.

SQL> select ename, sal from emp

where ename like 'J\_%' escape '\';

ENAME SAL

---------- ----------

J_SARA 700

J_PAGE 800

SQL> 2 where ename like 'J|_%' escape '|';

SQL> /

ENAME SAL

---------- ----------

J_SARA 700

J_PAGE 800

-- MYEMP1 테이블에서 이름이 ‘홍’으로 시작하는 사원들의 급여 최대값을 구하라.

SQL> SELECT MAX(SAL) FROM MYEMP1

WHERE ENAME LIKE '홍%'

MAX(SAL)

----------

5999995

IS[NOT] NULL : NULL 값인지의 여부를 검사, NULL을 검사하기 위한 유일한 연산자, 원래 NULL을 가지고 어떠한 연산이라도 할 수 없다. NULL인지 비교하기 위해 ‘=’, ‘!=’ 연산자를 이용하는 것은 잘못된 방식이다.

SQL> select count(*) from emp

2 where comm is null;

COUNT(*)

----------

11

SQL> 2 where comm = NULL

SQL> /

COUNT(*)

----------

0

-- MYEMP1 테이블의 COMM 칼럼에 인덱스를 만들자.

SQL> CREATE INDEX IDX_MYEMP1_COMM ON MYEMP1(COMM);

-- MYEMP1 테이블에서 COMM이 NULL인 사원의 수를 출력하세요. IS NULL은 인덱스를 사용하지 못한다. 인덱스 영역에는 NULL값은 보관하지 않는다.

SQL> SELECT COUNT(*) FROM MYEMP1

WHERE COMM IS NULL;

COUNT(*)

----------

8333335

경 과: 00:00:16.63

Execution Plan

---------------------------------------------------------------------------------------------

Id Operation Name Rows Bytes Cost (%CPU) Time

---------------------------------------------------------------------------------------------

0 SELECT STATEMENT 1 13 25257 00:05:04

1 SORT AGGREGATE 1 13

* 2 TABLE ACCESS FULL MYEMP1 500K 6347K 25257 00:05:04

-- MYEMP1 테이블에서 COMM이 NULL이 아닌 사원의 수를 출력하세요. IS NOT NULL인 경우에는 인덱스를 사용함을 확인하고 실행시간도 위 쿼리와 비교하라.

SQL> SELECT COUNT(*) FROM MYEMP1

WHERE COMM IS NOT NULL;

COUNT(*)

----------

1666667

경 과: 00:00:00.49

Execution Plan

-----------------------------------------------------------------------------------------------------------

Id Operation Name Rows Bytes Cost (%CPU) Time

-----------------------------------------------------------------------------------------------------------

0 SELECT STATEMENT 1 13 1056 00:00:13

1 SORT AGGREGATE 1 13

* 2 INDEX FAST FULL SCAN IDX_MYEMP1_COMM 500K 6347K 1056 00:00:13

------------------------------------------------------------------------------------------------------------

댓글 없음:

댓글 쓰기

(C#교육동영상)C# ADO.NET 실습 ODP.NET/ODAC 설치 오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원

  (C#교육동영상)C# ADO.NET 실습  ODP.NET/ODAC 설치  오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원 https://www.youtube.com/watch?v=qIPU85yAlzc&list=PLxU-i...